diff --git a/.gitignore b/.gitignore index e12af6df..fddda592 100644 --- a/.gitignore +++ b/.gitignore @@ -146,3 +146,6 @@ juliapkg.json # igonore mlflow run files *mlruns* + +# ignore jabalizer files +jabalizer_temp/ diff --git a/Makefile b/Makefile index 9658ef7d..dd8cdaf6 100644 --- a/Makefile +++ b/Makefile @@ -24,10 +24,10 @@ style: flake8p mypy pyright black isort @echo This project passes style! test: - $(PYTHON) -m pytest -W error tests + $(PYTHON) -m pytest tests coverage: - $(PYTHON) -m pytest -W error\ + $(PYTHON) -m pytest \ --cov=src \ --cov-fail-under=$(MIN_COVERAGE) tests \ --no-cov-on-fail \ diff --git a/README.md b/README.md index 55e4ff03..c36cb46d 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,11 @@ On some systems, the installation of PySCF can be problematic. If you're a Windo #### Azure Quantum Resource Estimation To run resource estimation using Azure Quantum Resource Estimation (QRE) tool, one needs to have Azure QRE package configure. See [this tutorial](https://learn.microsoft.com/en-us/azure/quantum/intro-to-resource-estimation) for more information. +#### Jabalizer +Jabalizer is an alternate graph state compilation toolchain to ruby slippers. To install Jabalizer, you will need to have the Rust programming language installed on your machine and run `pip install '.[jabalizer]'` from the top-level directory of this repository. + +Jabalizer can provide drastically reduced resource counts for some circuits, but it is considerably slower than ruby slippers. It is recommended to use Jabalizer only for smaller circuits. + ## Usage See the [`examples`](examples) directory to learn more about how to use Bench-Q. diff --git a/benchmarks/test_get_qsp_program.py b/benchmarks/test_get_qsp_program.py index 2f12de14..7fd5b54a 100644 --- a/benchmarks/test_get_qsp_program.py +++ b/benchmarks/test_get_qsp_program.py @@ -2,10 +2,12 @@ import zipfile from pathlib import Path +import openfermion import pytest from benchq.algorithms.time_evolution import _n_block_encodings_for_time_evolution -from benchq.problem_embeddings import get_qsp_program +from benchq.conversions import get_pyliqtr_operator +from benchq.problem_embeddings.qsp import get_qsp_program from benchq.problem_ingestion import get_hamiltonian_from_file, get_vlasov_hamiltonian from benchq.problem_ingestion.molecular_hamiltonians import ( get_hydrogen_chain_hamiltonian_generator, @@ -27,9 +29,10 @@ def vlasov_test_case(): failure_tolerance = 1e-3 operator = get_vlasov_hamiltonian(k, alpha, nu, N) + pyliqtr_operator = get_pyliqtr_operator(operator) n_block_encodings = _n_block_encodings_for_time_evolution( - operator, evolution_time, failure_tolerance + pyliqtr_operator, evolution_time, failure_tolerance ) return pytest.param(operator, n_block_encodings, id="vlasov") @@ -40,22 +43,23 @@ def jw_test_case(): failure_tolerance = 1e-3 n_hydrogens = 2 - operator = get_hydrogen_chain_hamiltonian_generator( - n_hydrogens - ).get_active_space_hamiltonian() + instance = generate_hydrogen_chain_instance(n_hydrogens) + interaction_operator = instance.get_active_space_hamiltonian() + jw_operator = openfermion.jordan_wigner(interaction_operator) + pyliqtr_jw_operator = get_pyliqtr_operator(jw_operator) n_block_encodings = _n_block_encodings_for_time_evolution( - operator, evolution_time, failure_tolerance + pyliqtr_jw_operator, evolution_time, failure_tolerance ) return pytest.param( - operator, + pyliqtr_jw_operator, n_block_encodings, id=f"jw-{n_hydrogens}", ) -def fast_load_test_cases(): +def fast_load_hamiltonians(): evolution_time = 5 failure_tolerance = 1e-3 base_location = "./examples/data/" @@ -74,7 +78,7 @@ def _load_hamiltonian(name): return [ pytest.param( - (operator := _load_hamiltonian(name)), + (operator := get_pyliqtr_operator(_load_hamiltonian(name))), _n_block_encodings_for_time_evolution( operator, evolution_time, failure_tolerance ), @@ -92,7 +96,7 @@ def _load_hamiltonian(name): @pytest.mark.benchmark @pytest.mark.parametrize( "operator, n_block_encodings", - [vlasov_test_case(), jw_test_case(), *fast_load_test_cases()], + [vlasov_test_case(), jw_test_case(), *fast_load_hamiltonians()], ) def test_get_qsp_program(benchmark, operator, n_block_encodings): benchmark(get_qsp_program, operator, n_block_encodings) diff --git a/benchmarks/test_ruby_slippers_performance.py b/benchmarks/test_ruby_slippers_performance.py index 37666ceb..4b059e08 100644 --- a/benchmarks/test_ruby_slippers_performance.py +++ b/benchmarks/test_ruby_slippers_performance.py @@ -3,7 +3,8 @@ import pytest from orquestra.quantum.circuits import CNOT, RX, Circuit, H, S, X, Z -from benchq.compilation import jl, pyliqtr_transpile_to_clifford_t +from benchq.compilation.circuits import pyliqtr_transpile_to_clifford_t +from benchq.compilation.graph_states import jl @pytest.mark.parametrize( diff --git a/benchmarks/test_substrate_scheduler_performance.py b/benchmarks/test_substrate_scheduler_performance.py index c95e29fa..a789d2ed 100644 --- a/benchmarks/test_substrate_scheduler_performance.py +++ b/benchmarks/test_substrate_scheduler_performance.py @@ -1,7 +1,9 @@ import networkx as nx import pytest -from benchq.resource_estimators.graph_estimators import substrate_scheduler +from benchq.compilation.graph_states.substrate_scheduler.python_substrate_scheduler import ( + python_substrate_scheduler, +) @pytest.mark.parametrize("preset", ["fast", "optimized"]) @@ -13,7 +15,7 @@ class TestSubstrateScheduler: @pytest.mark.parametrize("size", [10, 100, 1000]) def test_substrate_scheduler_timing(self, benchmark, graph, size, preset): graph = graph(size) - benchmark(substrate_scheduler, graph, preset) + benchmark(python_substrate_scheduler, graph, preset) @pytest.mark.parametrize( "graph", @@ -24,7 +26,7 @@ def test_substrate_scheduler_timing_with_pre_mapping_optimizer( self, benchmark, graph, size, preset ): graph = graph(size) - benchmark(substrate_scheduler, graph, preset) + benchmark(python_substrate_scheduler, graph, preset) @pytest.mark.parametrize("chain_size", [10, 100]) @pytest.mark.parametrize("bell_size", [10, 100]) @@ -32,7 +34,7 @@ def test_substrate_scheduler_timing_barbell_graph( self, benchmark, chain_size, bell_size, preset ): graph = nx.barbell_graph(chain_size, bell_size) - benchmark(substrate_scheduler, graph, preset) + benchmark(python_substrate_scheduler, graph, preset) @pytest.mark.parametrize("size", [10, 100]) @pytest.mark.parametrize("probablity_of_edge", [0.01, 0.1]) @@ -40,4 +42,4 @@ def test_substrate_scheduler_timing_erdos_renyi( self, benchmark, size, probablity_of_edge, preset ): graph = nx.erdos_renyi_graph(size, probablity_of_edge, seed=123) - benchmark(substrate_scheduler, graph, preset) + benchmark(python_substrate_scheduler, graph, preset) diff --git a/examples/data/single_rotation.qasm b/examples/data/single_rotation.qasm index ed5995d8..19bb67fa 100644 --- a/examples/data/single_rotation.qasm +++ b/examples/data/single_rotation.qasm @@ -1,5 +1,4 @@ OPENQASM 2.0; include "qelib1.inc"; -qreg q[4]; -h q[0]; -rz(0.20103392) q[0]; +qreg q[1]; +rx(0.20103392) q[0]; diff --git a/examples/ex_11_utility_scale.py b/examples/ex_10_utility_scale.py similarity index 65% rename from examples/ex_11_utility_scale.py rename to examples/ex_10_utility_scale.py index 6db6c5c6..d51662bd 100644 --- a/examples/ex_11_utility_scale.py +++ b/examples/ex_10_utility_scale.py @@ -1,30 +1,27 @@ -import datetime import json -import os import typing import warnings -from pathlib import Path from typing import Literal from benchq.algorithms.time_evolution import qsp_time_evolution_algorithm -from benchq.compilation import get_ruby_slippers_compiler +from benchq.compilation.graph_states.circuit_compilers import ( + get_ruby_slippers_circuit_compiler, +) +from benchq.compilation.graph_states.implementation_compiler import ( + get_implementation_compiler, +) from benchq.decoder_modeling import DecoderModel from benchq.problem_ingestion.solid_state_hamiltonians.ising import ( generate_ising_hamiltonian_on_cubic_lattice, generate_ising_hamiltonian_on_kitaev_lattice, generate_ising_hamiltonian_on_triangular_lattice, ) -from benchq.quantum_hardware_modeling import DETAILED_ION_TRAP_ARCHITECTURE_MODEL -from benchq.resource_estimators.footprint_estimators.openfermion_estimator import ( - footprint_estimator, -) -from benchq.resource_estimators.graph_estimators import ( - ExtrapolationResourceEstimator, - create_big_graph_from_subcircuits, - get_custom_extrapolated_estimate, - remove_isolated_nodes, - transpile_to_native_gates, +from benchq.quantum_hardware_modeling import ( + BASIC_SC_ARCHITECTURE_MODEL, + DETAILED_ION_TRAP_ARCHITECTURE_MODEL, ) +from benchq.resource_estimators.graph_estimator import GraphResourceEstimator +from benchq.resource_estimators.openfermion_estimator import openfermion_estimator def get_resources(lattice_type: str, size: int, decoder_data_file: str): @@ -38,60 +35,44 @@ def get_resources(lattice_type: str, size: int, decoder_data_file: str): else: raise ValueError(f"Lattice type {lattice_type} not supported") - architecture_model = DETAILED_ION_TRAP_ARCHITECTURE_MODEL + architecture_model = BASIC_SC_ARCHITECTURE_MODEL print("Getting algorithm implementation...") evolution_time = 1 - failure_tolerance = 1e-4 + failure_tolerance = 1e-3 algorithm_implementation = qsp_time_evolution_algorithm( operator, evolution_time, failure_tolerance ) print("Setting resource estimation parameters...") decoder_model = DecoderModel.from_csv(decoder_data_file) - my_estimator = ExtrapolationResourceEstimator( - architecture_model, - [2, 4, 6, 8, 10], - n_measurement_steps_fit_type="logarithmic", - optimization="space", - decoder_model=decoder_model, + circuit_compiler = get_ruby_slippers_circuit_compiler( + teleportation_threshold=80, optimal_dag_density=10 ) - - # select teleportation threshold to tune number of logical qubits - if lattice_type == "triangular": - gpm = get_ruby_slippers_compiler(teleportation_threshold=70) - elif lattice_type == "kitaev": - gpm = get_ruby_slippers_compiler(teleportation_threshold=60) - elif lattice_type == "cubic": - gpm = get_ruby_slippers_compiler(teleportation_threshold=70) - else: - raise ValueError(f"Lattice type {lattice_type} not supported") + implementation_compiler = get_implementation_compiler( + circuit_compiler, destination="single-thread" + ) + estimator = GraphResourceEstimator(optimization="Space", verbose=True) print("Estimating resources via graph state compilation...") - gsc_resources = get_custom_extrapolated_estimate( + gsc_resources = estimator.compile_and_estimate( algorithm_implementation, - my_estimator, - transformers=[ - transpile_to_native_gates, - create_big_graph_from_subcircuits(gpm), - remove_isolated_nodes, - ], - ) - - total_t_gates = my_estimator.get_n_total_t_gates( - gsc_resources.extra.n_t_gates, - gsc_resources.extra.n_rotation_gates, - algorithm_implementation.error_budget.transpilation_failure_tolerance, + implementation_compiler, + architecture_model, + decoder_model, ) + total_t_gates = algorithm_implementation.n_t_gates_after_transpilation hw_tolerance = algorithm_implementation.error_budget.hardware_failure_tolerance - footprint_resources = footprint_estimator( + + footprint_resources = openfermion_estimator( algorithm_implementation.program.num_data_qubits, num_t=total_t_gates, - architecture_model=my_estimator.hw_model, + architecture_model=architecture_model, hardware_failure_tolerance=hw_tolerance, decoder_model=decoder_model, ) + return gsc_resources, footprint_resources @@ -138,7 +119,7 @@ def main( save_results = False path_to_save_results = "." - utiliy_scale_problems: typing.Dict[ + utility_scale_problems: typing.Dict[ Literal["triangular", "kitaev", "cubic"], int ] = {"triangular": 30, "kitaev": 22, "cubic": 10} @@ -152,7 +133,7 @@ def main( decoder_data, save_results, lattice_type, - utiliy_scale_problems[lattice_type], + utility_scale_problems[lattice_type], path_to_save_results, ) diff --git a/examples/ex_1_from_qasm.py b/examples/ex_1_from_qasm.py index a84739ca..e85e451c 100644 --- a/examples/ex_1_from_qasm.py +++ b/examples/ex_1_from_qasm.py @@ -9,19 +9,14 @@ import os -from orquestra.integrations.qiskit.conversions import import_from_qiskit from qiskit.circuit import QuantumCircuit from benchq.algorithms.data_structures import AlgorithmImplementation, ErrorBudget -from benchq.problem_embeddings import get_program_from_circuit -from benchq.quantum_hardware_modeling import BASIC_SC_ARCHITECTURE_MODEL -from benchq.resource_estimators.graph_estimators import ( - GraphResourceEstimator, - create_big_graph_from_subcircuits, - get_custom_resource_estimation, - synthesize_clifford_t, - transpile_to_native_gates, +from benchq.compilation.graph_states.implementation_compiler import ( + get_implementation_compiler, ) +from benchq.quantum_hardware_modeling import BASIC_SC_ARCHITECTURE_MODEL +from benchq.resource_estimators.graph_estimator import GraphResourceEstimator def main(file_name): @@ -43,27 +38,18 @@ def main(file_name): qiskit_circuit, error_budget, 1 ) + # Here we run the resource estimation pipeline: # Architecture model is used to define the hardware model. architecture_model = BASIC_SC_ARCHITECTURE_MODEL - - # Here we run the resource estimation pipeline. - # In this case before performing estimation we use the following transformers: - # 1. Simplify rotations – it is a simple transpilation that removes redundant - # rotations from the circuit, such as RZ(0) or RZ(2pi) and replaces RX and RY - # gates with RZs - # 2. Gate synthesis – replaces all RZ gates with Clifford+T gates - # 3. Create big graph from subcircuits – this transformer is used to create - # a graph from subcircuits. It is needed to perform resource estimation using - # the graph resource estimator. In this case we use delayed gate synthesis, as - # we have already performed gate synthesis in the previous step. - gsc_resource_estimates = get_custom_resource_estimation( + # Create the estimator object, we can optimize for "Time" or "Space" + estimator = GraphResourceEstimator(optimization="Time", verbose=True) + # Use the default compiler + compiler = get_implementation_compiler() + # Put all the pieces together to get a resource estimate + gsc_resource_estimates = estimator.compile_and_estimate( algorithm_implementation, - estimator=GraphResourceEstimator(architecture_model), - transformers=[ - transpile_to_native_gates, - synthesize_clifford_t(error_budget), - create_big_graph_from_subcircuits(), - ], + compiler, + architecture_model, ) print("Resource estimation results:") print(gsc_resource_estimates) @@ -71,4 +57,4 @@ def main(file_name): if __name__ == "__main__": current_directory = os.path.dirname(__file__) - main(current_directory + "/data/example_circuit.qasm") + main(current_directory + "/data/ghz_circuit.qasm") diff --git a/examples/ex_2_time_evolution.py b/examples/ex_2_time_evolution.py index ab94f295..924e74f9 100644 --- a/examples/ex_2_time_evolution.py +++ b/examples/ex_2_time_evolution.py @@ -11,42 +11,44 @@ Most of the objects has been described in the `1_from_qasm.py` examples, here we only explain new concepts. -WARNING: This example requires the pyscf extra. run `pip install benchq[pyscf]` -to install the extra. +WARNING: This example requires the pyscf extra as well as the sdk extra. +run `pip install benchq[pyscf]` then `pip install benchq[sdk]` from the +main to install the extras. Then run `orq start` to start local ray. """ from pprint import pprint +from time import time from benchq.algorithms.time_evolution import qsp_time_evolution_algorithm + +# Requires jabalizer install. See README. +# from benchq.compilation.graph_states import get_jabalizer_circuit_compiler +from benchq.compilation.graph_states import get_ruby_slippers_circuit_compiler +from benchq.compilation.graph_states.implementation_compiler import ( + get_implementation_compiler, +) from benchq.problem_ingestion import get_vlasov_hamiltonian from benchq.problem_ingestion.solid_state_hamiltonians.heisenberg import ( generate_1d_heisenberg_hamiltonian, ) from benchq.quantum_hardware_modeling import BASIC_SC_ARCHITECTURE_MODEL -from benchq.resource_estimators.graph_estimators import ( - GraphResourceEstimator, - create_big_graph_from_subcircuits, - get_custom_resource_estimation, - synthesize_clifford_t, - transpile_to_native_gates, -) +from benchq.resource_estimators.graph_estimator import GraphResourceEstimator from benchq.timing import measure_time def main(): evolution_time = 5 - architecture_model = BASIC_SC_ARCHITECTURE_MODEL - + start_time = time() # Generating Hamiltonian for a given set of parameters, which # defines the problem we try to solve. # measure_time is a utility tool which measures the execution time of # the code inside the with statement. with measure_time() as t_info: - N = 2 # Problem size - operator = get_vlasov_hamiltonian(N=N, k=2.0, alpha=0.6, nu=0) + N = 3 # Problem size + # Get a Vlasov Hamiltonian for simulation + operator = get_vlasov_hamiltonian(N=N, k=2.0, alpha=0.6, nu=0) # Alternative operator: 1D Heisenberg model - # N = 100 # operator = generate_1d_heisenberg_hamiltonian(N) print("Operator generation time:", t_info.total) @@ -56,38 +58,32 @@ def main(): # In this example we perform time evolution using the QSP algorithm. with measure_time() as t_info: algorithm = qsp_time_evolution_algorithm(operator, evolution_time, 1e-3) - print("Circuit generation time:", t_info.total) - # First we perform resource estimation with gate synthesis at the circuit level. - # It's more accurate and leads to lower estimates, but also more expensive - # in terms of runtime and memory usage. - # Then we perform resource estimation with gate synthesis during the measurement, - # which we call "delayed gate synthesis". - with measure_time() as t_info: - gsc_resource_estimates = get_custom_resource_estimation( - algorithm, - estimator=GraphResourceEstimator(architecture_model), - transformers=[ - synthesize_clifford_t(algorithm.error_budget), - create_big_graph_from_subcircuits(), - ], - ) - - print("Resource estimation time with synthesis:", t_info.total) - pprint(gsc_resource_estimates) + print("Circuit generation time:", t_info.total) + print("n qubits in circuit:", algorithm.program.subroutines[0].n_qubits) + + # Allows for parallelized compilation. Uses ruby slippers compiler by default. + # The single-thread setting is simplest to use. You can parallelize on a local + # machine by setting the destination to "local" and running `orq up` in the + # terminal. Additional settings as well as using a remote cluster can be + # configured by using other settings available in the get_implementation_compiler + implementation_compiler = get_implementation_compiler( + circuit_compiler=get_ruby_slippers_circuit_compiler(), + destination="single-thread", + ) + estimator = GraphResourceEstimator(optimization="Time", verbose=True) with measure_time() as t_info: - gsc_resource_estimates = get_custom_resource_estimation( + resource_estimate = estimator.compile_and_estimate( algorithm, - estimator=GraphResourceEstimator(architecture_model), - transformers=[ - transpile_to_native_gates, - create_big_graph_from_subcircuits(), - ], + implementation_compiler, + BASIC_SC_ARCHITECTURE_MODEL, ) print("Resource estimation time without synthesis:", t_info.total) - pprint(gsc_resource_estimates) + pprint(resource_estimate) + + print("Total time to estimate resources:", time() - start_time) if __name__ == "__main__": diff --git a/examples/ex_3_packages_comparison.py b/examples/ex_3_packages_comparison.py index e2b05b6a..4db60f95 100644 --- a/examples/ex_3_packages_comparison.py +++ b/examples/ex_3_packages_comparison.py @@ -14,16 +14,15 @@ from pprint import pprint from benchq.algorithms.time_evolution import qsp_time_evolution_algorithm +from benchq.compilation.graph_states import ( + get_implementation_compiler, + get_ruby_slippers_circuit_compiler, +) from benchq.decoder_modeling import DecoderModel from benchq.problem_ingestion import get_vlasov_hamiltonian from benchq.quantum_hardware_modeling import BASIC_SC_ARCHITECTURE_MODEL -from benchq.resource_estimators.azure_estimator import AzureResourceEstimator -from benchq.resource_estimators.graph_estimators import ( - GraphResourceEstimator, - create_big_graph_from_subcircuits, - get_custom_resource_estimation, - transpile_to_native_gates, -) +from benchq.resource_estimators.azure_estimator import azure_estimator +from benchq.resource_estimators.graph_estimator import GraphResourceEstimator from benchq.timing import measure_time @@ -46,34 +45,40 @@ def main(): print("Circuit generation time:", t_info.total) + # We can adjust some of the parameters of the graph state compilation method. + # Here I've included some of the most important ones as an example. + circuit_compiler = get_ruby_slippers_circuit_compiler( + optimal_dag_density=10, + teleportation_threshold=60, + ) + # We run the resource estimation pipeline using the graph state compilation method. # In this example we do not transpile to a clifford + T circuit, as this is more # similar to how Azure QRE works. with measure_time() as t_info: - gsc_resource_estimates = get_custom_resource_estimation( + implementation_compiler = get_implementation_compiler( + circuit_compiler=circuit_compiler, destination="single-thread" + ) + gsc_estimator = GraphResourceEstimator(optimization="Time", verbose=True) + gsc_resource_estimates = gsc_estimator.compile_and_estimate( algorithm, - estimator=GraphResourceEstimator( - hw_model=architecture_model, decoder_model=decoder_model - ), - transformers=[ - transpile_to_native_gates, - create_big_graph_from_subcircuits(), - ], + implementation_compiler, + architecture_model, + decoder_model=decoder_model, ) print("Resource estimation time with GSC:", t_info.total) pprint(gsc_resource_estimates) - # AzureResourceEstimator is a wrapper around Azure QRE. It takes the same arguments + # azure_estimator is a wrapper around Azure QRE. It takes the same arguments # as GraphResourceEstimator, but instead of running the graph state compilation # method, it runs the Azure QRE. # Azure QRE takes in quantum circuits as input and performs compilation internally, # so there's no need for using any transformers. with measure_time() as t_info: - azure_resource_estimates = get_custom_resource_estimation( + azure_resource_estimates = azure_estimator( algorithm, - estimator=AzureResourceEstimator(), - transformers=[], + architecture_model=architecture_model, ) print("Resource estimation time with Azure:", t_info.total) diff --git a/examples/ex_4_fast_graph_estimates.py b/examples/ex_4_fast_graph_estimates.py index 7a55f0c1..a6d30187 100644 --- a/examples/ex_4_fast_graph_estimates.py +++ b/examples/ex_4_fast_graph_estimates.py @@ -45,7 +45,9 @@ def main(): print("Circuit generation time:", t_info.total) with measure_time() as t_info: - fast_gsc_resources = get_fast_graph_estimate(algorithm, architecture_model) + fast_gsc_resources = get_fast_graph_estimate( + algorithm, architecture_model, optimization="Time" + ) print("Resource estimation time with GSC:", t_info.total) pprint(fast_gsc_resources) diff --git a/examples/ex_5_qsp_re_with_orquestra/defs.py b/examples/ex_5_qsp_re_with_orquestra/defs.py index 59c02011..6dae0625 100644 --- a/examples/ex_5_qsp_re_with_orquestra/defs.py +++ b/examples/ex_5_qsp_re_with_orquestra/defs.py @@ -10,17 +10,13 @@ from benchq.algorithms.data_structures import ErrorBudget from benchq.algorithms.time_evolution import qsp_time_evolution_algorithm +from benchq.compilation.graph_states import get_implementation_compiler from benchq.problem_ingestion import get_vlasov_hamiltonian from benchq.quantum_hardware_modeling.hardware_architecture_models import ( BASIC_SC_ARCHITECTURE_MODEL, ) -from benchq.resource_estimators.azure_estimator import AzureResourceEstimator -from benchq.resource_estimators.graph_estimators import ( - GraphResourceEstimator, - create_big_graph_from_subcircuits, - get_custom_resource_estimation, - transpile_to_native_gates, -) +from benchq.resource_estimators.azure_estimator import azure_estimator +from benchq.resource_estimators.graph_estimator import GraphResourceEstimator task_deps = [ sdk.PythonImports("pyscf==2.2.0"), @@ -64,13 +60,12 @@ def get_operator(problem_size): @task_with_julia def gsc_estimates(algorithm, architecture_model): - return get_custom_resource_estimation( + implementation_compiler = get_implementation_compiler(destination="single-thread") + estimator = GraphResourceEstimator(optimization="Time", verbose=True) + return estimator.compile_and_estimate( algorithm, - estimator=GraphResourceEstimator(hw_model=architecture_model), - transformers=[ - transpile_to_native_gates, - create_big_graph_from_subcircuits(), - ], + implementation_compiler, + BASIC_SC_ARCHITECTURE_MODEL, ) @@ -104,11 +99,7 @@ def azure_estimates(algorithm, architecture_model): ) print("Original error message:", e) - return get_custom_resource_estimation( - algorithm, - estimator=AzureResourceEstimator(), - transformers=[], - ) + return azure_estimator(algorithm, architecture_model) @sdk.workflow diff --git a/examples/ex_7_mlflow.py b/examples/ex_6_mlflow.py similarity index 80% rename from examples/ex_7_mlflow.py rename to examples/ex_6_mlflow.py index e74e4c29..bab7fc55 100644 --- a/examples/ex_7_mlflow.py +++ b/examples/ex_6_mlflow.py @@ -10,19 +10,16 @@ from qiskit.circuit import QuantumCircuit from benchq.algorithms.data_structures import AlgorithmImplementation, ErrorBudget +from benchq.compilation.graph_states.implementation_compiler import ( + get_implementation_compiler, +) from benchq.mlflow.data_logging import ( log_input_objects_to_mlflow, log_resource_info_to_mlflow, ) -from benchq.problem_embeddings.quantum_program import get_program_from_circuit +from benchq.problem_embeddings import QuantumProgram from benchq.quantum_hardware_modeling import BASIC_SC_ARCHITECTURE_MODEL -from benchq.resource_estimators.graph_estimators import ( - GraphResourceEstimator, - create_big_graph_from_subcircuits, - get_custom_resource_estimation, - synthesize_clifford_t, - transpile_to_native_gates, -) +from benchq.resource_estimators.graph_estimator import GraphResourceEstimator def main(file_name, total_failure_tolerance=1e-3): @@ -33,7 +30,7 @@ def main(file_name, total_failure_tolerance=1e-3): qiskit_circuit = QuantumCircuit.from_qasm_file(file_name) # In order to perform resource estimation we need to translate it to a # benchq program. - quantum_program = get_program_from_circuit(import_from_qiskit(qiskit_circuit)) + quantum_program = QuantumProgram.from_circuit(import_from_qiskit(qiskit_circuit)) # Error budget is used to define what should be the failure rate of running # the whole calculation. It also allows to set relative weights for different @@ -60,14 +57,12 @@ def main(file_name, total_failure_tolerance=1e-3): # a graph from subcircuits. It is needed to perform resource estimation using # the graph resource estimator. In this case we use delayed gate synthesis, as # we have already performed gate synthesis in the previous step. - gsc_resource_estimates = get_custom_resource_estimation( + implementation_compiler = get_implementation_compiler(destination="single-thread") + estimator = GraphResourceEstimator(optimization="Time", verbose=True) + gsc_resource_estimates = estimator.compile_and_estimate( algorithm_implementation, - estimator=GraphResourceEstimator(architecture_model), - transformers=[ - transpile_to_native_gates, - synthesize_clifford_t(error_budget), - create_big_graph_from_subcircuits(), - ], + implementation_compiler, + architecture_model, ) # mlflow.set_tracking_uri("http://127.0.0.1:5000") @@ -75,7 +70,7 @@ def main(file_name, total_failure_tolerance=1e-3): log_input_objects_to_mlflow( algorithm_implementation, "simple qiskit circuit", - BASIC_SC_ARCHITECTURE_MODEL, + architecture_model, ) log_resource_info_to_mlflow(gsc_resource_estimates) diff --git a/examples/ex_6_orquestra_customized/defs.py b/examples/ex_6_orquestra_customized/defs.py deleted file mode 100644 index 9291680e..00000000 --- a/examples/ex_6_orquestra_customized/defs.py +++ /dev/null @@ -1,133 +0,0 @@ -"""Workflow and task definitions. - -To run this on Orquestra or locally use ``run.py`` script in the same directory. -""" - -from dataclasses import replace -from typing import List - -from orquestra import sdk - -from benchq.algorithms.data_structures import ( - AlgorithmImplementation, - ErrorBudget, - GraphPartition, -) -from benchq.algorithms.time_evolution import qsp_time_evolution_algorithm -from benchq.problem_ingestion import get_vlasov_hamiltonian -from benchq.quantum_hardware_modeling import ( - BASIC_ION_TRAP_ARCHITECTURE_MODEL, - BASIC_SC_ARCHITECTURE_MODEL, - BasicArchitectureModel, -) -from benchq.resource_estimators.graph_estimators import ( - GraphResourceEstimator, - create_big_graph_from_subcircuits, - transpile_to_native_gates, -) -from benchq.resource_estimators.resource_info import GraphResourceInfo - -task_deps = [ - sdk.PythonImports( - "pyscf==2.2.0", "openfermionpyscf==0.5", "stim==1.10", "juliapkg" - ), - sdk.GithubImport( - "zapatacomputing/benchq", - ), -] - -task = sdk.task( - source_import=sdk.InlineImport(), - dependency_imports=task_deps, - resources=sdk.Resources(memory="4Gi"), - custom_image="hub.nexus.orquestra.io/users/james.clark/benchq-ce:0.50.0", -) - - -@task -def get_algorithm_implementation( - problem_size: int, evolution_time: float, error_budget: ErrorBudget -) -> AlgorithmImplementation: - """Task producing algorithm implementation. - - The produced algorithm is QSP time evolution algorithm, with given evolution - time and error budget. The operator used is vlasov_hamiltonian of given size. - """ - return qsp_time_evolution_algorithm( - hamiltonian=get_vlasov_hamiltonian(N=problem_size, k=2.0, alpha=0.0, nu=0), - time=evolution_time, - failure_tolerance=error_budget.total_failure_tolerance, - ) - - -@task -def compile( - algorithm_implementation: AlgorithmImplementation, -) -> AlgorithmImplementation: - """Transpile algorithm implementation into a graph representationp. - - The transpilation has two steps: - - 1. Simplifying rotations - 2. Converting the QuantumProgram of the algorithm into a graph representation. - """ - compiled_algorithm = replace( - algorithm_implementation, - program=create_big_graph_from_subcircuits()( - transpile_to_native_gates(algorithm_implementation.program) - ), - ) - - if not isinstance(compiled_algorithm.program, GraphPartition): - raise TypeError( - f"Expected AlgorithmImplementation[GraphPartition]," - f"got {type(compiled_algorithm)}" - ) - - return compiled_algorithm - - -@task -def estimate_resources( - algorithm_implementation: AlgorithmImplementation, - architecture_model: BasicArchitectureModel, -) -> GraphResourceInfo: - """Estimate resources for algorithm impl., assuming given architecture_model.""" - return GraphResourceEstimator(hw_model=architecture_model).estimate( - algorithm_implementation - ) - - -@sdk.workflow(resources=sdk.Resources(memory="8Gi", nodes=2)) -def estimation_workflow() -> List[sdk.ArtifactFuture[GraphResourceInfo]]: - """The workflow for estimating resources. - - The workflow does the following: - 1. Creates algorithm implementation. - 2. Transpiles it into a graph representation. - 3. Defines two architecture models. - 4. Estimates the resources for the constructed algorithm implementation assuming - the defined hardware models. - - The last step can be parallelized. - - The workflow does not use pieplines defined in benchq, and hence the graph - compilation is not repeated for each hardware model, bur rather computed - once and reused. - """ - algorithm = get_algorithm_implementation( - problem_size=2, - evolution_time=5.0, - error_budget=ErrorBudget.from_even_split(total_failure_tolerance=1e-3), - ) - - architecture_models: List[BasicArchitectureModel] = [ - BASIC_SC_ARCHITECTURE_MODEL, - BASIC_ION_TRAP_ARCHITECTURE_MODEL, - ] - - compiled_algorithm = compile(algorithm) - - return [ - estimate_resources(compiled_algorithm, model) for model in architecture_models - ] diff --git a/examples/ex_6_orquestra_customized/run.py b/examples/ex_6_orquestra_customized/run.py deleted file mode 100644 index e4f9aa1a..00000000 --- a/examples/ex_6_orquestra_customized/run.py +++ /dev/null @@ -1,50 +0,0 @@ -"""Script for running estimation workflow. - -Synopsis: -usage: run.py [-h] target - -positional arguments: - target where to run the workflow (e.g. in_process or name of the orquestra - cluster). This argument is passed to Workflow.run method. - -options: - -h, --help show this help message and exit - -This file uses relative imports, and hence has to be launched as module from outside -of its parent directory. For intsance, to launch it from benchq main directory, run: - -python -m examples.ex_6_orquestra_customized.run in_process -""" -import argparse -from time import sleep - -from orquestra.sdk.schema.workflow_run import State - -from .defs import estimation_workflow - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument( - "target", - help=( - "where to run the workflow (e.g. in_process or name of the orquestra " - "cluster). This argument is passed to Workflow.run method." - ), - type=str, - ) - - args = parser.parse_args() - - wf = estimation_workflow() - - wf_run = wf.run(args.target) - print(f"Workflow {wf_run.run_id} submitted!") - - wf_run.wait_until_finished() - - print(wf_run.get_results()) - - -if __name__ == "__main__": - main() diff --git a/examples/ex_8_remote_mlflow/defs.py b/examples/ex_7_remote_mlflow/defs.py similarity index 86% rename from examples/ex_8_remote_mlflow/defs.py rename to examples/ex_7_remote_mlflow/defs.py index d204e82a..98928fac 100644 --- a/examples/ex_8_remote_mlflow/defs.py +++ b/examples/ex_7_remote_mlflow/defs.py @@ -12,6 +12,7 @@ from benchq.algorithms.data_structures import ErrorBudget from benchq.algorithms.time_evolution import qsp_time_evolution_algorithm +from benchq.compilation.graph_states import get_implementation_compiler from benchq.mlflow.data_logging import ( log_input_objects_to_mlflow, log_resource_info_to_mlflow, @@ -20,12 +21,7 @@ from benchq.quantum_hardware_modeling.hardware_architecture_models import ( BASIC_SC_ARCHITECTURE_MODEL, ) -from benchq.resource_estimators.graph_estimators import ( - GraphResourceEstimator, - create_big_graph_from_subcircuits, - get_custom_resource_estimation, - transpile_to_native_gates, -) +from benchq.resource_estimators.graph_estimator import GraphResourceEstimator task_deps = [ sdk.PythonImports("pyscf==2.2.0", "openfermionpyscf==0.5"), @@ -66,13 +62,12 @@ def get_operator(problem_size): @gsc_task def gsc_estimates(algorithm, architecture_model): - resource_info = get_custom_resource_estimation( + estimator = GraphResourceEstimator() + implementation_compiler = get_implementation_compiler() + resource_info = estimator.compile_and_estimate( algorithm, - estimator=GraphResourceEstimator(hw_model=architecture_model), - transformers=[ - transpile_to_native_gates, - create_big_graph_from_subcircuits(), - ], + implementation_compiler, + architecture_model, ) f = open(os.environ["ORQUESTRA_PASSPORT_FILE"], "r") diff --git a/examples/ex_8_remote_mlflow/run.py b/examples/ex_7_remote_mlflow/run.py similarity index 100% rename from examples/ex_8_remote_mlflow/run.py rename to examples/ex_7_remote_mlflow/run.py diff --git a/examples/ex_9_scf_mlflow/defs.py b/examples/ex_8_scf_mlflow/defs.py similarity index 100% rename from examples/ex_9_scf_mlflow/defs.py rename to examples/ex_8_scf_mlflow/defs.py diff --git a/examples/ex_9_scf_mlflow/run.py b/examples/ex_8_scf_mlflow/run.py similarity index 100% rename from examples/ex_9_scf_mlflow/run.py rename to examples/ex_8_scf_mlflow/run.py diff --git a/examples/ex_10_lde_solver.py b/examples/ex_9_lde_solver.py similarity index 96% rename from examples/ex_10_lde_solver.py rename to examples/ex_9_lde_solver.py index ce10e712..f1b17504 100644 --- a/examples/ex_10_lde_solver.py +++ b/examples/ex_9_lde_solver.py @@ -13,11 +13,11 @@ ) from orquestra.quantum.decompositions._decomposition import DecompositionRule -from benchq.compilation import ( +from benchq.compilation.circuits import ( + compile_to_native_gates, pyliqtr_transpile_to_clifford_t, - transpile_to_native_gates, ) -from benchq.compilation.transpile_to_native_gates import decompose_benchq_circuit +from benchq.compilation.circuits.compile_to_native_gates import decompose_benchq_circuit from benchq.problem_embeddings.block_encodings.offset_tridiagonal import ( get_offset_tridagonal_block_encoding, ) @@ -150,7 +150,7 @@ def run_time_marching(): decomposed_cir = decompose_benchq_circuit( time_marching_cir, [Remove_Multicontrol()] ) - native_gates = transpile_to_native_gates(decomposed_cir) + native_gates = compile_to_native_gates(decomposed_cir) clifford_t = pyliqtr_transpile_to_clifford_t(native_gates, 1e-2) quantum_program = clifford_t print(f"Number of T and T_dag gates: {quantum_program.n_t_gates}") diff --git a/examples/plot_time_data.py b/examples/plot_time_data.py new file mode 100644 index 00000000..a7c18acd --- /dev/null +++ b/examples/plot_time_data.py @@ -0,0 +1,53 @@ +import matplotlib.pyplot as plt +import numpy as np + + +def plot_log_log_with_fit(times, problem_sizes): + # Convert lists to numpy arrays for mathematical operations + log_times = np.log(times) + log_sizes = np.log(problem_sizes) + + # Fit a line to the logarithmic values + coefficients = np.polyfit(log_sizes, log_times, 1) + poly = np.poly1d(coefficients) + + # Create an extended range of problem sizes up to 20 + extended_sizes = np.linspace(min(problem_sizes), 20, 100) + + # Calculate fitted values over the extended range + fit_values = np.exp(poly(np.log(extended_sizes))) + + # Plotting the original data + plt.scatter(problem_sizes, times, color="blue", label="Original data") + + # Plotting the fit over the extended range + plt.plot( + extended_sizes, + fit_values, + color="red", + label=f"Fit: y = {coefficients[0]:.2f}x + {np.exp(coefficients[1]):.2f}", + ) + + # Setting the scale to log-log + plt.xscale("log") + plt.yscale("log") + + # Labels and legend + plt.xlabel("Lattice Size") + plt.ylabel("Time") + plt.title("Log-Log Plot with Linear Fit Extended to Lattice Size 20") + plt.legend() + + # Display the plot + plt.show() + + +# Example usage +problem_sizes = [6, 8, 10, 12] +times = [ + 73.17189908027649, + 118.44559001922607, + 175.57360100746155, + 236.62325501441956, +] +plot_log_log_with_fit(times, problem_sizes) diff --git a/examples/toy_problem_demo.ipynb b/examples/toy_problem_demo.ipynb index 7bd78f6f..850f3e1b 100644 --- a/examples/toy_problem_demo.ipynb +++ b/examples/toy_problem_demo.ipynb @@ -1,796 +1,820 @@ { - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Toy Problem Demo\n", - "\n", - "## Scope\n", - "\n", - "Overview of Benchq:\n", - "- inputs and outputs\n", - "- components:\n", - " - Transpilation (pyliqtr)\n", - " - Jabalizer/ICM\n", - " - Min code distance finding\n", - " - Substrate scheduling\n", - "\n", - "\n", - "Wait a little for TA 1 and TA 1.5\n", - "\n", - "### Goal: Introduction to Benchq Tool for Resource Estimation" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Agenda\n", - "- Quick overview of Benchq usage.\n", - "- What is a circuit graph? How do we produce them?\n", - "- How do circuit graphs help get resource estimates?\n", - "- Look at some pretty plots\n", - " - Preparing a GHZ state\n", - " - The fully connected graph" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Introduction to Graph Estimators\n", - "\n", - "Let's go through a gory example of what benchq is doing for the case of a graph resource estimator.\n", - "\n", - "First we need to import some things and install a python environment in your python installation. This might take a minute.\n", - "\n", - "Running this line will install julia to your python installation. See README for details." - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "from qiskit import QuantumCircuit\n", - "import networkx as nx\n", - "\n", - "from benchq.compilation import get_algorithmic_graph_from_Jabalizer, pyliqtr_transpile_to_clifford_t\n", - "from benchq.resource_estimators.graph_estimators import (\n", - " GraphResourceEstimator,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [], - "source": [ - "from benchq.quantum_hardware_modeling import BASIC_SC_ARCHITECTURE_MODEL\n", - "\n", - "demo_circuit = QuantumCircuit.from_qasm_file(\"data/single_rotation.qasm\")\n", - "architecture_model = BASIC_SC_ARCHITECTURE_MODEL" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, transpile into Clifford + T." - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Circuit(operations=[H(0), S†(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0)], n_qubits=4)\n" - ] - } - ], - "source": [ - "clifford_t_circuit = pyliqtr_transpile_to_clifford_t(\n", - " demo_circuit, circuit_precision=1e-6\n", - ")\n", - "print(clifford_t_circuit)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Transform circuit into graph." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "update_tableau: \tcurrent_inverse_tableau: 0.000047 seconds (3 allocations: 72 bytes)\n", - "\tinverse: 0.000748 seconds (4 allocations: 72 bytes)\n", - "\tupdate stabilizers: \n", - "\t66:\t1.424s, elapsed time: 0.02 min\n", - " 1.487114 seconds (1.33 M allocations: 86.719 MiB, 2.84% gc time, 90.70% compilation time)\n", - " 1.555618 seconds (1.34 M allocations: 87.759 MiB, 2.72% gc time, 90.99% compilation time)\n", - "\tsort!: 0.000071 seconds (1 allocation: 576 bytes)\n", - "\tMake X-block upper triangular: 0.000014 seconds (1 allocation: 144 bytes)\n", - "\tMake diagonal: 0.000008 seconds\n", - "\tPhase correction and checks: 0.000002 seconds (1 allocation: 672 bytes)\n", - "\tCheck symmetry: 0.000012 seconds\n" - ] - } - ], - "source": [ - "circuit_graph = get_algorithmic_graph_from_Jabalizer(clifford_t_circuit)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With this use this graph to make resource estimates." - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "getting max graph degree\n", - "starting substrate scheduler\n", - "substrate scheduler took 0.012549877166748047 seconds\n", - "ResourceInfo(code_distance=15, logical_error_rate=0.0014768016621208176, n_logical_qubits=27, n_physical_qubits=67600, total_time_in_seconds=0.00633, decoder_info=None, magic_state_factory_name='(15-to-1)^6_15,5,5 x (20-to-4)_23,11,13', routing_to_measurement_volume_ratio=0.14786729857819905, extra=GraphData(max_graph_degree=27, n_nodes=3206, n_t_gates=62, n_rotation_gates=0, n_measurement_steps=104), hardware_resource_info=None)\n" - ] - } - ], - "source": [ - "from benchq.resource_estimators.graph_estimators import GraphResourceEstimator\n", - "from benchq.algorithms.data_structures import (\n", - " AlgorithmImplementation,\n", - " ErrorBudget,\n", - " GraphPartition,\n", - ")\n", - "from benchq.problem_embeddings.quantum_program import QuantumProgram\n", - "\n", - "# only allow a failure to occur 1% of the time\n", - "budget = ErrorBudget.from_even_split(1e-2)\n", - "program = GraphPartition(\n", - " QuantumProgram.from_circuit(clifford_t_circuit), [circuit_graph]\n", - ")\n", - "implementation = AlgorithmImplementation(program, budget, 1)\n", - "estimator = GraphResourceEstimator(architecture_model)\n", - "\n", - "resource_estimates = estimator.estimate(implementation)\n", - "print(resource_estimates)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Summary\n", - "\n", - "#### Minimal Inputs:\n", - "- Circuit\n", - "- Archetecture Model\n", - "\n", - "#### Outputs:\n", - "- Number of physical qubits\n", - "- Computation time\n", - "- number of measurement steps (will be important later on!)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Pipelines\n", - "\n", - "#### Example usage\n", - "\n", - "Typically, one would use a pipeline to combine all these steps into one command that benchq can follow.\n", - "\n", - "Here we use one of the pre-configured pipelines called `get_precise_graph_estimate`." - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Transpiling to native gates...\n", - "Transpiled in 0.00019979476928710938 seconds.\n", - "Creating big graph from subcircuits...\n", - "getting networkx graph from vertices\n", - "time: 0.0003001689910888672\n", - "getting max graph degree\n", - "get_graph_state_data:\tstarting substrate scheduler\n", - "substrate scheduler took 0.0001990795135498047 seconds\n", - "Memory for data structures allocated\n", - "100% (64) completed in 0.0s\n", - " 0.000582 seconds (2.33 k allocations: 102.625 KiB)\n", - "ResourceInfo(code_distance=14, logical_error_rate=0.0013524576608630586, n_logical_qubits=18, n_physical_qubits=57412, total_time_in_seconds=0.0024648, decoder_info=None, magic_state_factory_name='(15-to-1)^6_15,5,5 x (20-to-4)_23,11,13', routing_to_measurement_volume_ratio=0.08860759493670886, extra=GraphData(max_graph_degree=18, n_nodes=26, n_t_gates=26, n_rotation_gates=0, n_measurement_steps=26), hardware_resource_info=None)\n" - ] - } - ], - "source": [ - "from benchq.resource_estimators.default_estimators import (\n", - " get_precise_graph_estimate,\n", - ")\n", - "from benchq.conversions import import_circuit\n", - "\n", - "# only allow a failure to occur 1% of the time\n", - "budget = ErrorBudget.from_even_split(1e-2)\n", - "implementation = AlgorithmImplementation.from_circuit(demo_circuit, budget, 1)\n", - "resource_estimate = get_precise_graph_estimate(implementation, architecture_model)\n", - "\n", - "print(resource_estimate)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Default Pipelines\n", - "Benchq offers 5 default pipelines:\n", - "\n", - "1. `get_precise_graph_estimate` - This pipeline uses the most accurate methods for estimating the resources required to run a circuit on a given architecture. It is also the slowest.\n", - "2. `get_fast_graph_estimate` - This pipeline uses faster methods for estimating the resources required to run a circuit on a given architecture. It is also less accurate.\n", - "3. `get_precise_extrapolation_estimate` - This pipeline uses the most accurate methods for estimating the resources required to get part of the graph. It will then extrapolate out to the size of the full graph.\n", - "4. `get_fast_extrapolation_estimate` - This pipeline uses the fastest methods for estimating the resources required to get part of the graph. It will then extrapolate out to the size of the full graph.\n", - "5. `get_footprint_estimate` - This pipeline is the fastest estimate, but is also the least accurate. It counts the number of T gates in the circuit and gets a space optimized estimate from that.\n", - "\n", - "They can be imported with the following command:\n", - "\n", - "```python\n", - "import benchq.resource_estimators.default_estimators import \n", - "```\n", - "\n", - "And run with the same inputs as above." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## What is a a Circuit Graph?" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "update_tableau: \tcurrent_inverse_tableau: 0.000011 seconds (3 allocations: 72 bytes)\n", - "\tinverse: 0.000566 seconds (4 allocations: 72 bytes)\n", - "\tupdate stabilizers: \n", - "\t66:\t0.002s, elapsed time: 0.0 min\n", - " 0.002034 seconds (4.78 k allocations: 183.203 KiB)\n", - " 0.002976 seconds (4.86 k allocations: 188.289 KiB)\n", - "\tsort!: 0.000073 seconds (1 allocation: 576 bytes)\n", - "\tMake X-block upper triangular: 0.000012 seconds (1 allocation: 144 bytes)\n", - "\tMake diagonal: 0.000011 seconds\n", - "\tPhase correction and checks: 0.000003 seconds (1 allocation: 672 bytes)\n", - "\tCheck symmetry: 0.000010 seconds\n" - ] - } - ], - "source": [ - "this_circuit_graph = get_algorithmic_graph_from_Jabalizer(clifford_t_circuit)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What does this do?\n", - "\n", - "Recall that our circuit is in clifford + T form\n", - "\n", - "- Replaces T gates with magic measurements and ancilla\n", - "- Use stabilizer simulator efficiently to push single qubit cliffords to one side\n", - "- Now we have a circuit of the form Initialization, CNOT, Measurement (ICM form)" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Circuit(operations=[H(0), S†(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0)], n_qubits=4)\n" - ] - } - ], - "source": [ - "print(clifford_t_circuit)" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Circuit(operations=[H(0), S†(0), H(0), S(0), CNOT(0,4), H(4), S(4), CNOT(4,5), H(5), CNOT(5,6), H(6), CNOT(6,7), H(7), S(7), CNOT(7,8), H(8), CNOT(8,9), H(9), CNOT(9,10), H(10), CNOT(10,11), H(11), S(11), CNOT(11,12), H(12), S(12), CNOT(12,13), H(13), CNOT(13,14), H(14), CNOT(14,15), H(15), S(15), CNOT(15,16), H(16), CNOT(16,17), H(17), CNOT(17,18), H(18), CNOT(18,19), H(19), CNOT(19,20), H(20), S(20), CNOT(20,21), H(21), CNOT(21,22), H(22), S(22), CNOT(22,23), H(23), S(23), CNOT(23,24), H(24), CNOT(24,25), H(25), S(25), CNOT(25,26), H(26), CNOT(26,27), H(27), CNOT(27,28), H(28), CNOT(28,29), H(29), CNOT(29,30), H(30), CNOT(30,31), H(31), CNOT(31,32), H(32), S(32), CNOT(32,33), H(33), S(33), CNOT(33,34), H(34), S(34), CNOT(34,35), H(35), S(35), CNOT(35,36), H(36), CNOT(36,37), H(37), CNOT(37,38), H(38), CNOT(38,39), H(39), S(39), CNOT(39,40), H(40), S(40), CNOT(40,41), H(41), CNOT(41,42), H(42), CNOT(42,43), H(43), CNOT(43,44), H(44), S(44), CNOT(44,45), H(45), S(45), CNOT(45,46), H(46), CNOT(46,47), H(47), S(47), CNOT(47,48), H(48), S(48), CNOT(48,49), H(49), CNOT(49,50), H(50), S(50), CNOT(50,51), H(51), S(51), CNOT(51,52), H(52), S(52), CNOT(52,53), H(53), CNOT(53,54), H(54), S(54), CNOT(54,55), H(55), CNOT(55,56), H(56), CNOT(56,57), H(57), CNOT(57,58), H(58), S(58), CNOT(58,59), H(59), S(59), CNOT(59,60), H(60), S(60), CNOT(60,61), H(61), S(61), CNOT(61,62), H(62), CNOT(62,63), H(63), CNOT(63,64), H(64), S(64), CNOT(64,65)], n_qubits=66)\n" - ] - } - ], - "source": [ - "import data.get_icm as icm\n", - "\n", - "circuit_after_icm = icm.get_icm(clifford_t_circuit)\n", - "print(circuit_after_icm)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The middle CNOTS are the interesting part:\n", - "\n", - "- The CNOTS make a graph state\n", - "- Use stabilizer simulator to find graph state (Jabalizer)\n", - "- Return graph state as circuit graph" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAApQAAAHzCAYAAACe1o1DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABiFElEQVR4nO3ddzzVewMH8I9oqiRaKkVbU5pu0XATbe1I5TboNrW0x23einZpK9qlUtSlQXvqttwGCqVBQoqM8/xxb56EooPvGZ/369XrXr9znPO5zyM+vuunIpFIJCAiIiIi+kmFRAcgIiIiIvnGQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikoqa6ABERF8EhsUgNCoBetrqMNTVFB1H5vIQEckqFkoikglLfYKwKSAk/WN7E304WdQTlmeJ90O4XgiVmTxERLJMRSKRSESHICLlFhgWg14bL2e6PrkxULnoZ3z+/BnJycn4/Plzln++99jPPC4pWw3lbZZnytNZ9T7aNaiGBg0aoHbt2ihSpEhB/M9DRCTzWCiJSKjw8HDM3n4C5xN1Mz0W5bUSCQ/OZbimpqaGwoULo0iRIpn+ZHf9e49ldf1xchmcjNbOlCfl4na8uHgkPUedOnXQoEGD9D/169eHvr4+VFVV8+d/LCIiGcVCSUQF7uPHjzh69Ch27twJPz8/lKzWAGUHLMn0vK396sBQVzND+StUKP/3EmY3YurpYIxqJSV48OAB7t+/n/7Pe/fu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r49ChRRjlUhiYiLu3r0Lr8v3sPt1xQyPlW7VB0MdjFkmiYgox1goSanpaWd9fuLyOVMQfucC/P394ejoiOTkZJQtWxZt27ZNL5iNGzeGmprs/xX6Uh5v3bqFmzdv4tatW3jw4AFSUlJQqpEZylpOyPQ5oVEJMNTVLPiwREQklzjlTUrv2ylfB1N9TOv8/zWUHz9+xNWrV+Hv74+AgABcvXoViYmJKFWqFNq0aQNTU1OYmJigWbNmKFy4sIj/hHTfK49qampo0KABjIyM0KxZMxgZGSFNUxf9t93M9DqeDsYslERElGMslET4/6YUPW31HxappKQk3LhxI71gXrp0CQkJCShRogRat26dXjBbtmyJYsWK5Vvm3JbHhg0bZpnnR4WaiIjoR1goiaSUnJyMwMBA+Pv7w9/fHxcvXkRsbCyKFi2Kli1bpk+Rt27dOstbFOakzOakPH4pjt8rj9nJTaEmIiL6FgslUR5LTU3F3bt3ERAQkD6KGR0dDTU1NTRr1iy9YP7yyy/YePllhtFBexN9TGiv993y2LBhw/Ti+DPlkYiIKK+xUBLls7S0NAQFBaWXS39/f7x69QrFKtdFhcErMj3/jfsUfIoIYnkkIiK5wUJJVMAkEgmePn2KtSeu4/ibMpke76oVjSGm9VgeiYhIbrBQEgkSGBaDXhsvZ7rOHdZERCRvFOOUZiI5ZKirCXsT/QzXHEz1WSaJiEjucISSSDDusCYiInnHQklEREREUuGUNxERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCQVFkoiIiIikgoLJRERERFJhYWSiIiIiKTCQklEREREUmGhJCIiIiKpsFASERERkVRYKImIiIhIKiyURERERCSV/wEiO5Jaimt0YAAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "nx.draw(circuit_graph, node_size=10)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here we see a simple chain graph because our circuit structure simpy passes the qubits down the line generated by decomposing to clifford + T." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Summary\n", - "\n", - "Circuit graphs are generated from the icm form of a circuit.\n", - "\n", - "They are a representation of the graph state that is generated by the circuit." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Getting Resource Estimates from Circuit Graphs\n", - "\n", - "Rather than keep the whole graph, we extract the information we need to get resource estimates.\n", - "\n", - "We store this in a `GraphData` object.\n", - "\n", - "Let's make a `GraphData` object from our demo circuit." - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "getting max graph degree\n", - "starting substrate scheduler\n", - "substrate scheduler took 0.011377811431884766 seconds\n", - "GraphData(max_graph_degree=27, n_nodes=3206, n_t_gates=62, n_rotation_gates=0, n_measurement_steps=104)\n" - ] - } - ], - "source": [ - "from benchq.algorithms.data_structures import GraphPartition\n", - "\n", - "# we have to wrap `circuit_graph` in a `GraphPartition` object,\n", - "# but you can ignore that as it is usually done internally\n", - "graph_partition = GraphPartition(program, [circuit_graph])\n", - "\n", - "graph_data = estimator._get_graph_data_for_single_graph(graph_partition)\n", - "print(graph_data)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you can see, the graph data involves some data that comes from how the graph was made including `n_t_gates` and `n_rotation_gates`.\n", - "\n", - "`n_measurement_steps` is the number of measurement steps required to prepare that graph_state. It is used to calculate the time required to prepare the graph state.\n", - "\n", - "Next, let's use `graph_data`` to get some resource estimates." - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "distance: 15\n", - "physical qubit count: 28920\n", - "total time: 0.0030787200000000005\n" - ] - } - ], - "source": [ - "from benchq.magic_state_distillation.litinski_factories import (\n", - " iter_litinski_factories,\n", - ")\n", - "\n", - "# One of Litinski's magic state distillation factories. A small one should be just fine for this instance\n", - "magic_state_factory = iter_litinski_factories(architecture_model)[0]\n", - "\n", - "logical_qubit_count = len(circuit_graph)\n", - "\n", - "n_total_t_gates = estimator.get_n_total_t_gates(\n", - " graph_data.n_t_gates,\n", - " graph_data.n_rotation_gates,\n", - " budget.transpilation_failure_tolerance,\n", - ")\n", - "\n", - "distance = estimator._minimize_code_distance(\n", - " n_total_t_gates,\n", - " graph_data,\n", - " architecture_model.physical_qubit_error_rate, # physical error\n", - " magic_state_factory,\n", - ")\n", - "physical_qubit_count = estimator._get_n_physical_qubits(\n", - " graph_data, distance, magic_state_factory\n", - ")\n", - "total_time = estimator._get_time_per_circuit_in_seconds(\n", - " graph_data, distance, n_total_t_gates, magic_state_factory\n", - ")\n", - "\n", - "\n", - "print(f\"distance: {distance}\")\n", - "print(f\"physical qubit count: {physical_qubit_count}\")\n", - "print(f\"total time: {total_time}\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And there you go! We have some resource estimates.\n", - "\n", - "Don't worry if the estimates are a little high, that's just because we didn't choose a smaller magic state factory for this calculation." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How to make Circuit Graph State?\n", - "\n", - "Since graph state is a stabilizer state, we measure stabilizers to generate it!\n", - "\n", - "We could measure all the stabilizers to get the graph.\n", - "\n", - "Measurements are expensive!! So how optimize?\n", - "\n", - "### Substrate Scheduler\n", - "\n", - "Tells us how to measure and which can be measured simultaneously." - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "starting substrate scheduler\n", - "substrate scheduler took 0.13897085189819336 seconds\n", - "[[518, 2814, 2907, 3003, 3103], [2724, 2815, 2908, 3004, 3104], [2000, 2314, 2391, 2470, 2551, 2636, 2725, 2816, 2909, 3005, 3105], [2240, 2315, 2392, 2471, 2552, 2637, 2726, 2817, 2910, 3006, 3106], [68, 79, 92, 106, 117, 129, 141, 153, 164, 177, 189, 202, 213, 226, 240, 250, 259, 273, 285, 296, 308, 322, 333, 346, 357, 369, 381, 393, 405, 416, 429, 440, 453, 466, 477, 516, 535, 550, 565, 580, 595, 610, 625, 640, 666, 688, 710, 732, 754, 776, 800, 825, 850, 875, 902, 931, 960, 989, 1018, 1051, 1085, 1120, 1155, 1190, 1224, 1260, 1300, 1342, 1384, 1431, 1477, 1525, 1575, 1625, 1677, 1731, 1787, 1845, 1905, 1967, 2032, 2099, 2168, 2241, 2316, 2393, 2472, 2553, 2638, 2727, 2818, 2911, 3007, 3107], [498, 1301, 1343, 1385, 1432, 1478, 1526, 1576, 1626, 1678, 1732, 1788, 1846, 1906, 1968, 2033, 2100, 2169, 2242, 2317, 2394, 2473, 2554, 2639, 2728, 2819, 2912, 3008, 3108], [7, 17, 28, 37, 48, 58, 70, 82, 93, 107, 118, 131, 142, 154, 167, 178, 191, 200, 214, 225, 237, 249, 263, 274, 286, 298, 309, 321, 334, 345, 359, 370, 383, 394, 407, 417, 430, 441, 454, 465, 478, 495, 536, 551, 566, 581, 596, 611, 626, 641, 667, 689, 711, 733, 755, 777, 801, 826, 851, 876, 903, 932, 961, 990, 1019, 1050, 1086, 1122, 1156, 1191, 1227, 1261, 1302, 1344, 1386, 1433, 1479, 1527, 1577, 1627, 1679, 1733, 1789, 1847, 1907, 1969, 2034, 2101, 2170, 2243, 2318, 2395, 2474, 2555, 2640, 2729, 2820, 2913, 3009, 3109], [1263, 1303, 1345, 1387, 1434, 1480, 1528, 1578, 1628, 1680, 1734, 1790, 1848, 1908, 1970, 2035, 2102, 2171, 2244, 2319, 2396, 2475, 2556, 2641, 2730, 2821, 2914, 3010, 3110], [1388, 1435, 1481, 1529, 1579, 1629, 1681, 1735, 1791, 1849, 1909, 1971, 2036, 2103, 2172, 2245, 2320, 2397, 2476, 2557, 2642, 2731, 2822, 2915, 3011, 3111], [530, 1436, 1482, 1530, 1580, 1630, 1682, 1736, 1792, 1850, 1910, 1972, 2037, 2104, 2173, 2246, 2321, 2398, 2477, 2558, 2643, 2732, 2823, 2916, 3012, 3112], [501, 1437, 1483, 1531, 1581, 1631, 1683, 1737, 1793, 1851, 1911, 1973, 2038, 2105, 2174, 2247, 2322, 2399, 2478, 2559, 2644, 2733, 2824, 2917, 3013, 3113], [1392, 1438, 1484, 1532, 1582, 1632, 1684, 1738, 1794, 1852, 1912, 1974, 2039, 2106, 2175, 2248, 2323, 2400, 2479, 2560, 2645, 2734, 2825, 2918, 3014, 3114], [512, 2561, 2646, 2735, 2826, 2919, 3015, 3115], [499, 1304, 1346, 1393, 1439, 1485, 1533, 1583, 1633, 1685, 1739, 1795, 1853, 1913, 1975, 2040, 2107, 2176, 2249, 2324, 2401, 2480, 2562, 2647, 2736, 2827, 2920, 3016, 3116], [2481, 2563, 2648, 2737, 2828, 2921, 3017, 3117], [514, 2564, 2649, 2738, 2829, 2922, 3018, 3118], [2482, 2565, 2650, 2739, 2830, 2923, 3019, 3119], [496, 1052, 1087, 1121, 1157, 1192, 1226, 1262, 1305, 1347, 1394, 1440, 1486, 1534, 1584, 1634, 1686, 1740, 1796, 1854, 1914, 1976, 2041, 2108, 2177, 2250, 2325, 2402, 2483, 2566, 2651, 2740, 2831, 2924, 3020, 3120], [1264, 1306, 1348, 1395, 1441, 1487, 1535, 1585, 1635, 1687, 1741, 1797, 1855, 1915, 1977, 2042, 2109, 2178, 2251, 2326, 2403, 2484, 2567, 2652, 2741, 2832, 2925, 3021, 3121], [502, 1688, 1742, 1798, 1856, 1916, 1978, 2043, 2110, 2179, 2252, 2327, 2404, 2485, 2568, 2653, 2742, 2833, 2926, 3022, 3122], [500, 1307, 1349, 1396, 1442, 1488, 1536, 1586, 1636, 1689, 1743, 1799, 1857, 1917, 1979, 2044, 2111, 2180, 2253, 2328, 2405, 2486, 2569, 2654, 2743, 2834, 2927, 3023, 3123], [1637, 1690, 1744, 1800, 1858, 1918, 1980, 2045, 2112, 2181, 2254, 2329, 2406, 2487, 2570, 2655, 2744, 2835, 2928, 3024, 3124], [503, 1691, 1745, 1801, 1859, 1919, 1981, 2046, 2113, 2182, 2255, 2330, 2407, 2488, 2571, 2656, 2745, 2836, 2929, 3025, 3125], [1638, 1692, 1746, 1802, 1860, 1920, 1982, 2047, 2114, 2183, 2256, 2331, 2408, 2489, 2572, 2657, 2746, 2837, 2930, 3026, 3126], [1266, 1308, 1350, 1397, 1443, 1489, 1537, 1587, 1639, 1693, 1747, 1803, 1861, 1921, 1983, 2048, 2115, 2184, 2257, 2332, 2409, 2490, 2573, 2658, 2747, 2838, 2931, 3027, 3127], [1265, 1309, 1351, 1398, 1444, 1490, 1538, 1588, 1640, 1694, 1748, 1804, 1862, 1922, 1984, 2049, 2116, 2185, 2258, 2333, 2410, 2491, 2574, 2659, 2748, 2839, 2932, 3028, 3128], [46, 60, 71, 86, 95, 105, 121, 130, 143, 155, 166, 179, 192, 203, 215, 227, 238, 252, 262, 275, 288, 299, 311, 323, 335, 347, 358, 371, 382, 395, 406, 419, 431, 445, 455, 467, 479, 488, 537, 552, 567, 582, 597, 612, 627, 642, 668, 690, 712, 734, 756, 778, 802, 827, 852, 877, 904, 933, 962, 991, 1020, 1053, 1088, 1123, 1158, 1193, 1229, 1268, 1310, 1352, 1399, 1445, 1491, 1539, 1589, 1641, 1695, 1749, 1805, 1863, 1923, 1985, 2050, 2117, 2186, 2259, 2334, 2411, 2492, 2575, 2660, 2749, 2840, 2933, 3029, 3129], [652, 2187, 2260, 2335, 2412, 2493, 2576, 2661, 2750, 2841, 2934, 3030, 3130], [1021, 1055, 1089, 1124, 1159, 1194, 1228, 1269, 1311, 1353, 1400, 1446, 1492, 1540, 1590, 1642, 1696, 1750, 1806, 1864, 1924, 1986, 2051, 2118, 2188, 2261, 2336, 2413, 2494, 2577, 2662, 2751, 2842, 2935, 3031, 3131], [2119, 2189, 2262, 2337, 2414, 2495, 2578, 2663, 2752, 2843, 2936, 3032, 3132], [2844, 2937, 3033, 3133], [519, 2938, 3034, 3134], [2845, 2939, 3035, 3135], [508, 2190, 2263, 2338, 2415, 2496, 2579, 2664, 2753, 2846, 2940, 3036, 3136], [2120, 2191, 2264, 2339, 2416, 2497, 2580, 2665, 2754, 2847, 2941, 3037, 3137], [497, 1054, 1090, 1125, 1160, 1195, 1230, 1270, 1312, 1354, 1401, 1447, 1493, 1541, 1591, 1643, 1697, 1751, 1807, 1865, 1925, 1987, 2052, 2121, 2192, 2265, 2340, 2417, 2498, 2581, 2666, 2755, 2848, 2942, 3038, 3138], [533, 1056, 1091, 1126, 1161, 1196, 1231, 1271, 1313, 1355, 1402, 1448, 1494, 1542, 1592, 1644, 1698, 1752, 1808, 1866, 1926, 1988, 2053, 2122, 2193, 2266, 2341, 2418, 2499, 2582, 2667, 2756, 2849, 2943, 3039, 3139], [1022, 1057, 1092, 1127, 1162, 1197, 1232, 1272, 1314, 1356, 1403, 1449, 1495, 1543, 1593, 1645, 1699, 1753, 1809, 1867, 1927, 1989, 2054, 2123, 2194, 2267, 2342, 2419, 2500, 2583, 2668, 2757, 2850, 2944, 3040, 3140], [1023, 1058, 1093, 1128, 1163, 1198, 1233, 1273, 1315, 1357, 1404, 1450, 1496, 1544, 1594, 1646, 1700, 1754, 1810, 1868, 1928, 1990, 2055, 2124, 2195, 2268, 2343, 2420, 2501, 2584, 2669, 2758, 2851, 2945, 3041, 3141], [779, 803, 828, 853, 878, 905, 934, 963, 992, 1024, 1059, 1094, 1129, 1164, 1199, 1234, 1274, 1316, 1358, 1405, 1451, 1497, 1545, 1595, 1647, 1701, 1755, 1811, 1869, 1929, 1991, 2056, 2125, 2196, 2269, 2344, 2421, 2502, 2585, 2670, 2759, 2852, 2946, 3042, 3142], [490, 804, 829, 854, 879, 906, 935, 964, 993, 1025, 1060, 1095, 1130, 1165, 1200, 1235, 1275, 1317, 1359, 1406, 1452, 1498, 1546, 1596, 1648, 1702, 1756, 1812, 1870, 1930, 1992, 2057, 2126, 2197, 2270, 2345, 2422, 2503, 2586, 2671, 2760, 2853, 2947, 3043, 3143], [780, 805, 830, 855, 880, 907, 936, 965, 994, 1026, 1061, 1096, 1131, 1166, 1201, 1237, 1276, 1318, 1360, 1407, 1453, 1499, 1547, 1597, 1649, 1703, 1757, 1813, 1871, 1931, 1993, 2058, 2127, 2198, 2271, 2346, 2423, 2504, 2587, 2672, 2761, 2854, 2948, 3044, 3144], [504, 1814, 1872, 1932, 1994, 2059, 2128, 2199, 2272, 2347, 2424, 2505, 2588, 2673, 2762, 2855, 2949, 3045, 3145], [9, 18, 27, 38, 49, 61, 72, 83, 98, 108, 119, 132, 145, 156, 169, 180, 190, 204, 216, 228, 239, 251, 264, 276, 287, 301, 312, 324, 336, 348, 360, 372, 384, 398, 408, 421, 432, 443, 456, 468, 480, 493, 538, 553, 568, 583, 598, 613, 628, 643, 669, 691, 713, 735, 757, 781, 806, 831, 856, 881, 908, 937, 966, 995, 1027, 1063, 1097, 1132, 1167, 1202, 1236, 1277, 1319, 1361, 1408, 1454, 1500, 1548, 1598, 1650, 1704, 1758, 1815, 1873, 1933, 1995, 2060, 2129, 2200, 2273, 2348, 2425, 2506, 2589, 2674, 2763, 2856, 2950, 3046, 3146], [1759, 1816, 1874, 1934, 1996, 2061, 2130, 2201, 2274, 2349, 2426, 2507, 2590, 2675, 2764, 2857, 2951, 3047, 3147], [1391, 1817, 1875, 1935, 1997, 2062, 2131, 2202, 2275, 2350, 2427, 2508, 2591, 2676, 2765, 2858, 2952, 3048, 3148], [506, 2063, 2132, 2203, 2276, 2351, 2428, 2509, 2592, 2677, 2766, 2859, 2953, 3049, 3149], [1760, 1818, 1876, 1936, 1998, 2064, 2133, 2204, 2277, 2352, 2429, 2510, 2593, 2678, 2767, 2860, 2954, 3050, 3150], [1999, 2065, 2134, 2205, 2278, 2353, 2430, 2511, 2594, 2679, 2768, 2861, 2955, 3051, 3151], [507, 2066, 2135, 2206, 2279, 2354, 2431, 2512, 2595, 2680, 2769, 2862, 2956, 3052, 3152], [1267, 2067, 2136, 2207, 2280, 2355, 2432, 2513, 2596, 2681, 2770, 2863, 2957, 3053, 3153], [2001, 2068, 2137, 2208, 2281, 2356, 2433, 2514, 2597, 2682, 2771, 2864, 2958, 3054, 3154], [8, 20, 29, 40, 50, 59, 73, 84, 96, 110, 120, 133, 144, 159, 168, 181, 193, 205, 217, 230, 242, 253, 265, 277, 289, 300, 313, 326, 337, 349, 361, 373, 385, 396, 410, 420, 434, 444, 457, 469, 483, 494, 539, 554, 569, 584, 599, 614, 629, 644, 670, 692, 714, 736, 758, 782, 807, 832, 857, 882, 909, 938, 967, 996, 1028, 1062, 1098, 1133, 1168, 1203, 1238, 1278, 1320, 1362, 1409, 1455, 1501, 1549, 1599, 1651, 1705, 1761, 1819, 1877, 1937, 2002, 2069, 2138, 2209, 2282, 2357, 2434, 2515, 2598, 2683, 2772, 2865, 2959, 3055, 3155], [505, 1938, 2003, 2070, 2139, 2210, 2283, 2358, 2435, 2516, 2599, 2684, 2773, 2866, 2960, 3056, 3156], [511, 2436, 2517, 2600, 2685, 2774, 2867, 2961, 3057, 3157], [515, 2686, 2775, 2868, 2962, 3058, 3158], [10, 19, 30, 39, 52, 63, 74, 85, 99, 111, 122, 134, 146, 157, 171, 182, 194, 206, 218, 229, 244, 254, 267, 278, 292, 302, 315, 325, 338, 350, 362, 375, 386, 397, 409, 422, 433, 446, 458, 470, 481, 523, 540, 555, 570, 585, 600, 615, 630, 645, 671, 693, 715, 737, 759, 783, 808, 833, 858, 883, 910, 939, 968, 997, 1029, 1065, 1099, 1134, 1170, 1204, 1239, 1279, 1321, 1363, 1410, 1456, 1502, 1550, 1600, 1652, 1706, 1762, 1820, 1878, 1939, 2004, 2071, 2140, 2211, 2284, 2359, 2437, 2518, 2601, 2687, 2776, 2869, 2963, 3059, 3159], [656, 3060, 3160], [2602, 2688, 2777, 2870, 2964, 3061, 3161], [2965, 3062, 3162], [657, 3063, 3163], [2966, 3064, 3164], [517, 2689, 2778, 2871, 2967, 3065, 3165], [2603, 2690, 2779, 2872, 2968, 3066, 3166], [2360, 2438, 2519, 2604, 2691, 2780, 2873, 2969, 3067, 3167], [654, 2439, 2520, 2605, 2692, 2781, 2874, 2970, 3068, 3168], [2361, 2440, 2521, 2606, 2693, 2782, 2875, 2971, 3069, 3169], [1879, 1940, 2005, 2072, 2141, 2212, 2285, 2362, 2441, 2522, 2607, 2694, 2783, 2876, 2972, 3070, 3170], [651, 1941, 2006, 2073, 2142, 2213, 2286, 2363, 2442, 2523, 2608, 2695, 2784, 2877, 2973, 3071, 3171], [1880, 1942, 2007, 2074, 2143, 2214, 2287, 2364, 2443, 2524, 2609, 2696, 2785, 2878, 2974, 3072, 3172], [11, 21, 31, 41, 51, 64, 75, 90, 97, 109, 124, 135, 147, 158, 172, 184, 195, 209, 220, 231, 241, 255, 266, 280, 290, 303, 314, 328, 340, 352, 363, 374, 388, 400, 411, 423, 435, 447, 459, 471, 482, 524, 541, 556, 571, 586, 601, 616, 631, 646, 672, 694, 716, 738, 760, 784, 809, 834, 859, 884, 911, 940, 969, 998, 1030, 1064, 1100, 1135, 1169, 1205, 1241, 1280, 1322, 1364, 1411, 1457, 1503, 1551, 1601, 1653, 1707, 1763, 1821, 1881, 1943, 2008, 2075, 2144, 2215, 2288, 2365, 2444, 2525, 2610, 2697, 2786, 2879, 2975, 3073, 3173], [522, 542, 557, 572, 587, 602, 617, 632, 647, 673, 695, 717, 739, 761, 785, 810, 835, 860, 885, 912, 941, 970, 999, 1031, 1067, 1101, 1136, 1171, 1206, 1240, 1281, 1323, 1365, 1412, 1458, 1504, 1552, 1602, 1654, 1708, 1764, 1822, 1882, 1944, 2009, 2076, 2145, 2216, 2289, 2366, 2445, 2526, 2611, 2698, 2787, 2880, 2976, 3074, 3174], [0, 2, 4, 6, 12, 22, 32, 42, 53, 62, 76, 87, 101, 113, 125, 136, 148, 160, 170, 183, 196, 207, 219, 232, 243, 257, 268, 279, 291, 306, 316, 327, 339, 353, 365, 376, 387, 401, 414, 424, 436, 449, 460, 472, 484, 525, 543, 558, 573, 588, 603, 618, 633, 648, 674, 696, 718, 740, 762, 786, 811, 836, 861, 886, 913, 942, 971, 1000, 1032, 1066, 1102, 1137, 1172, 1207, 1242, 1282, 1324, 1366, 1413, 1459, 1505, 1553, 1603, 1655, 1709, 1765, 1823, 1883, 1945, 2010, 2077, 2146, 2217, 2290, 2367, 2446, 2527, 2612, 2699, 2788, 2881, 2977, 3075, 3175], [526, 544, 559, 574, 589, 604, 619, 634, 649, 675, 697, 719, 741, 763, 787, 812, 837, 862, 887, 914, 943, 972, 1001, 1033, 1069, 1103, 1138, 1173, 1208, 1243, 1283, 1325, 1367, 1414, 1460, 1506, 1554, 1604, 1656, 1710, 1766, 1824, 1884, 1946, 2011, 2078, 2147, 2218, 2291, 2368, 2447, 2528, 2613, 2700, 2789, 2882, 2978, 3076, 3176], [650, 676, 698, 720, 742, 764, 788, 813, 838, 863, 888, 915, 944, 973, 1002, 1034, 1068, 1104, 1139, 1174, 1209, 1245, 1284, 1326, 1368, 1415, 1461, 1507, 1555, 1605, 1657, 1711, 1767, 1825, 1885, 1947, 2012, 2079, 2148, 2219, 2292, 2369, 2448, 2529, 2614, 2701, 2790, 2883, 2979, 3077, 3177], [653, 677, 699, 721, 743, 765, 789, 814, 839, 864, 889, 916, 945, 974, 1003, 1035, 1070, 1106, 1140, 1175, 1210, 1244, 1285, 1327, 1369, 1416, 1462, 1508, 1556, 1606, 1658, 1712, 1768, 1826, 1886, 1948, 2013, 2080, 2149, 2220, 2293, 2370, 2449, 2530, 2615, 2702, 2791, 2884, 2980, 3078, 3178], [510, 678, 700, 722, 744, 766, 790, 815, 840, 865, 890, 917, 946, 975, 1004, 1037, 1071, 1105, 1141, 1176, 1211, 1247, 1286, 1328, 1370, 1417, 1463, 1509, 1557, 1607, 1659, 1713, 1769, 1827, 1887, 1949, 2014, 2081, 2150, 2221, 2294, 2371, 2450, 2531, 2616, 2703, 2792, 2885, 2981, 3079, 3179], [489, 679, 701, 723, 745, 767, 791, 816, 841, 866, 891, 918, 947, 976, 1005, 1036, 1073, 1107, 1142, 1177, 1213, 1246, 1287, 1329, 1371, 1418, 1464, 1510, 1558, 1608, 1660, 1714, 1770, 1828, 1888, 1950, 2015, 2082, 2151, 2222, 2295, 2372, 2451, 2532, 2617, 2704, 2793, 2886, 2982, 3080, 3180], [658, 680, 702, 724, 746, 768, 792, 817, 842, 867, 892, 919, 948, 977, 1006, 1038, 1072, 1108, 1143, 1178, 1212, 1249, 1288, 1330, 1372, 1419, 1465, 1511, 1559, 1609, 1661, 1715, 1771, 1829, 1889, 1951, 2016, 2083, 2152, 2223, 2296, 2373, 2452, 2533, 2618, 2705, 2794, 2887, 2983, 3081, 3181], [531, 681, 703, 725, 747, 769, 793, 818, 843, 868, 893, 920, 949, 978, 1007, 1039, 1074, 1109, 1145, 1179, 1214, 1248, 1289, 1331, 1373, 1420, 1466, 1512, 1560, 1610, 1662, 1716, 1772, 1830, 1890, 1952, 2017, 2084, 2153, 2224, 2297, 2374, 2453, 2534, 2619, 2706, 2795, 2888, 2984, 3082, 3182], [520, 3183], [1389, 1561, 1611, 1663, 1717, 1773, 1831, 1891, 1953, 2018, 2085, 2154, 2225, 2298, 2375, 2454, 2535, 2620, 2707, 2796, 2889, 2985, 3083, 3184], [3084, 3185], [521, 3186], [3085, 3187], [660, 682, 704, 726, 748, 770, 794, 819, 844, 869, 894, 921, 950, 979, 1008, 1040, 1075, 1110, 1144, 1180, 1215, 1250, 1290, 1332, 1374, 1421, 1467, 1513, 1562, 1612, 1664, 1718, 1774, 1832, 1892, 1954, 2019, 2086, 2155, 2226, 2299, 2376, 2455, 2536, 2621, 2708, 2797, 2890, 2986, 3086, 3188], [1514, 1563, 1613, 1665, 1719, 1775, 1833, 1893, 1955, 2020, 2087, 2156, 2227, 2300, 2377, 2456, 2537, 2622, 2709, 2798, 2891, 2987, 3087, 3189], [1390, 1564, 1614, 1666, 1720, 1776, 1834, 1894, 1956, 2021, 2088, 2157, 2228, 2301, 2378, 2457, 2538, 2623, 2710, 2799, 2892, 2988, 3088, 3190], [1515, 1565, 1615, 1667, 1721, 1777, 1835, 1895, 1957, 2022, 2089, 2158, 2229, 2302, 2379, 2458, 2539, 2624, 2711, 2800, 2893, 2989, 3089, 3191], [528, 545, 560, 575, 590, 605, 620, 635, 661, 683, 705, 727, 749, 771, 795, 820, 845, 870, 895, 922, 951, 980, 1009, 1041, 1076, 1111, 1147, 1181, 1216, 1251, 1291, 1333, 1375, 1422, 1468, 1516, 1566, 1616, 1668, 1722, 1778, 1836, 1896, 1958, 2023, 2090, 2159, 2230, 2303, 2380, 2459, 2540, 2625, 2712, 2801, 2894, 2990, 3090, 3192], [13, 24, 33, 43, 54, 65, 77, 88, 102, 112, 123, 137, 150, 161, 174, 186, 197, 210, 221, 233, 246, 256, 270, 281, 293, 304, 317, 329, 341, 351, 364, 377, 389, 399, 415, 425, 437, 448, 461, 473, 485, 527, 546, 561, 576, 591, 606, 621, 636, 662, 684, 706, 728, 750, 772, 796, 821, 846, 871, 896, 923, 952, 981, 1010, 1043, 1077, 1112, 1146, 1182, 1217, 1252, 1292, 1334, 1376, 1423, 1469, 1517, 1567, 1617, 1669, 1723, 1779, 1837, 1897, 1959, 2024, 2091, 2160, 2231, 2304, 2381, 2460, 2541, 2626, 2713, 2802, 2895, 2991, 3091, 3193], [3, 14, 23, 34, 44, 55, 67, 78, 89, 103, 115, 126, 138, 149, 163, 173, 185, 198, 208, 223, 235, 245, 258, 269, 282, 295, 305, 319, 330, 343, 355, 366, 379, 390, 402, 412, 426, 438, 451, 463, 474, 486, 529, 547, 562, 577, 592, 607, 622, 637, 663, 685, 707, 729, 751, 773, 797, 822, 847, 872, 897, 924, 953, 982, 1011, 1042, 1079, 1113, 1148, 1183, 1219, 1253, 1293, 1335, 1377, 1424, 1470, 1518, 1568, 1618, 1670, 1724, 1780, 1838, 1898, 1960, 2025, 2092, 2161, 2232, 2305, 2382, 2461, 2542, 2627, 2714, 2803, 2896, 2992, 3092, 3194], [491, 925, 954, 983, 1012, 1045, 1078, 1114, 1149, 1184, 1218, 1255, 1294, 1336, 1378, 1425, 1471, 1519, 1569, 1619, 1671, 1725, 1781, 1839, 1899, 1961, 2026, 2093, 2162, 2233, 2306, 2383, 2462, 2543, 2628, 2715, 2804, 2897, 2993, 3093, 3195], [1, 15, 25, 35, 45, 56, 66, 80, 91, 100, 114, 127, 140, 151, 162, 175, 188, 199, 211, 222, 236, 248, 260, 271, 283, 294, 307, 318, 331, 344, 356, 367, 378, 391, 404, 413, 427, 442, 450, 464, 475, 487, 532, 548, 563, 578, 593, 608, 623, 638, 664, 686, 708, 730, 752, 774, 798, 823, 848, 873, 898, 926, 955, 984, 1013, 1044, 1080, 1115, 1150, 1186, 1220, 1254, 1295, 1337, 1379, 1426, 1472, 1520, 1570, 1620, 1672, 1726, 1782, 1840, 1900, 1962, 2027, 2094, 2163, 2234, 2307, 2384, 2463, 2544, 2629, 2716, 2805, 2898, 2994, 3094, 3196], [899, 927, 956, 985, 1014, 1047, 1081, 1116, 1151, 1185, 1221, 1256, 1296, 1338, 1380, 1427, 1473, 1521, 1571, 1621, 1673, 1727, 1783, 1841, 1901, 1963, 2028, 2095, 2164, 2235, 2308, 2385, 2464, 2545, 2630, 2717, 2806, 2899, 2995, 3095, 3197], [492, 928, 957, 986, 1015, 1046, 1082, 1117, 1152, 1187, 1223, 1257, 1297, 1339, 1381, 1428, 1474, 1522, 1572, 1622, 1674, 1728, 1784, 1842, 1902, 1964, 2029, 2096, 2165, 2236, 2309, 2386, 2465, 2546, 2631, 2718, 2807, 2900, 2996, 3096, 3198], [900, 929, 958, 987, 1016, 1048, 1083, 1118, 1153, 1188, 1222, 1258, 1298, 1340, 1382, 1429, 1475, 1523, 1573, 1623, 1675, 1729, 1785, 1843, 1903, 1965, 2030, 2097, 2166, 2237, 2310, 2387, 2466, 2547, 2632, 2719, 2808, 2901, 2997, 3097, 3199], [509, 2311, 2388, 2467, 2548, 2633, 2720, 2809, 2902, 2998, 3098, 3200], [5, 16, 26, 36, 47, 57, 69, 81, 94, 104, 116, 128, 139, 152, 165, 176, 187, 201, 212, 224, 234, 247, 261, 272, 284, 297, 310, 320, 332, 342, 354, 368, 380, 392, 403, 418, 428, 439, 452, 462, 476, 513, 534, 549, 564, 579, 594, 609, 624, 639, 665, 687, 709, 731, 753, 775, 799, 824, 849, 874, 901, 930, 959, 988, 1017, 1049, 1084, 1119, 1154, 1189, 1225, 1259, 1299, 1341, 1383, 1430, 1476, 1524, 1574, 1624, 1676, 1730, 1786, 1844, 1904, 1966, 2031, 2098, 2167, 2238, 2312, 2389, 2468, 2549, 2634, 2721, 2810, 2903, 2999, 3099, 3201], [655, 2811, 2904, 3000, 3100, 3202], [2239, 2313, 2390, 2469, 2550, 2635, 2722, 2812, 2905, 3001, 3101, 3203], [659], [2723, 2813, 2906, 3002, 3102, 3204], [3205]]\n" - ] - } - ], - "source": [ - "from benchq.resource_estimators.graph_estimators import substrate_scheduler\n", - "\n", - "compiler = substrate_scheduler(circuit_graph, \"fast\")\n", - "formatted_measurement_steps = [\n", - " [node[0] for node in step] for step in compiler.measurement_steps\n", - "]\n", - "\n", - "print(formatted_measurement_steps)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAApQAAAHzCAYAAACe1o1DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABneElEQVR4nO3dd3gU5cLG4d/spgKhhk6khhoCIQRCR3qRpqg0pSnYC5YDlg8s6FGxgh7BAiKioAIqKBCqhJqE3nvvPUBCkt35/ogEkBbYTWaTPPd15YQddmeezcHkyTvzvmOYpmkiIiIiInKHbFYHEBEREZGsTYVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUkmWYJpzcAQdjIem81WlERETkEi+rA4ikh9MBv/WFtd+nPs4VCD3/ghK1rc0lIiIiGqGULCL2S1g74fLjhFPwUycwndZlEhERkVQqlJIlHFwBht1Me2w6IP4gnDti3uRVIiIikhlUKCVLyF3UidNx9XBkChep1aAqb775Jrt377YmmIiIiKhQiudLSUnh+x1PcNbcD4aJ7Z8rf6s8t5dGTevx/vvvU7ZsWZo1a8b48eM5f14zdkRERDKTYZqmzhmKx0pOTqZnz55MnTqV78f8QunTnUg8BWXuhrJ3pz7n3LlzTJkyhXHjxjF//nzy5MlD165d6dOnD40aNcJm0+9NIiIiGUmFUjxWUlISDz74IDNmzODnn3+mU6dOt3zN7t27+f777xk3bhw7d+6k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ERERj6FCKXIdpmmyrn17qv71F15Xbvf2xoiPBzcujC4iIpLV6RpKkeswDIPQwoWvuUbSSE6GU6csSiUiIuKZVChFbiQiAsPpvPzYboeSJaFIEesyiYiIeCAVSpEbefxx6NXr8uMCBeC338Cm/2xERESupGsoRW5lxw44fRoqVwbN7BYREbmGCqWIiIiIuETn7kRERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGXqFCKiIiIiEtUKEVERETEJSqUIiIiIuISFUoRERERcYkKpYiIiIi4RIVSRERERFyiQikiIiIiLlGhFBERERGX/D/uTQ+LiaF45QAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from benchq.visualization_tools import plot_graph_state_with_measurement_steps\n", - "\n", - "plot_graph_state_with_measurement_steps(\n", - " compiler.input_graph, compiler.measurement_steps\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Problem! Graph can get too big to handle!\n", - "\n", - "#### Solution! Use subcircuits.\n", - "\n", - "Quantum Algorithms are made up of repeated components.\n", - "\n", - "Estimate resources for each component & multiply by the number of times it was used.\n", - "\n", - "Will create a higher estimate.\n", - "\n", - "More on this later!" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## FINALLY! Pretty Graph Time!\n", - "\n", - "Let's look at the graphs of circuits to examine measurement steps!" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "starting substrate scheduler\n", - "substrate scheduler took 7.510185241699219e-05 seconds\n", - "update_tableau: \tcurrent_inverse_tableau: 0.000027 seconds (3 allocations: 72 bytes)\n", - "\tinverse: 0.000053 seconds (4 allocations: 72 bytes)\n", - "\tupdate stabilizers: \n", - "\t4:\t0.0s, elapsed time: 0.0 min\n", - " 0.000534 seconds (312 allocations: 12.547 KiB)\n", - " 0.001515 seconds (392 allocations: 17.281 KiB)\n", - "\tsort!: 0.000001 seconds\n", - "\tMake X-block upper triangular: 0.000002 seconds (1 allocation: 144 bytes)\n", - "\tMake diagonal: 0.000002 seconds\n", - "\tPhase correction and checks: 0.000001 seconds\n", - "\tCheck symmetry: 0.000001 seconds\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAApQAAAHzCAYAAACe1o1DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAl5klEQVR4nO3deZxVBf3/8c+wCIhLKKhoIuOGmpmmafnN1DS1zMyFMHcDlNj3ZQANHJB9BwHRryIuuWvmV83MTC0zNbNcABG/LoggrogIzP390Rd+hNxzrl7g3Jl5Pv+BufN4zLzn8WDufd1zLueW5XK5XAAAwJdUJ+sBAABUb4ISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEqAPN5ZvTr+8emn8f6aNVlPAShp9bIeAFCKZr3/fkxYtixyEbFVRIzYaac4cZttsp4FUJLKcrlcLusRAKXk6RUr4vxFi/7jtvoR8UCLFrFzPc/DATbklDfABp5fufJzd46rImLeZ59lMQeg5AlKgA00q1cvqjZ2e926W3wLQHUgKAE2cELjxnFow4YRuVzkVq2KiIgzt902WjVokPEygNIkKAE2UL+sLGY1bx5tliyJpTNnRv+ysvhV06ZZzwIoWYISYCO2KiuLIz/+OJaMGxffjYiysrKsJwGULEEJkMfaiHQxDIBkghIgD0EJUBhBCZCHoAQojKAEyENQAhRGUALkISgBCiMoAfIQlACFEZQAeQhKgMIISoA8BCVAYQQlQB6CEqAwghIgD0EJUBhBCZCHoAQojKAEyENQAhRGUALkISgBCiMoAfIQlACFEZQAeQhKgMIISoA8BCVAYQQlQB6CEqAwghIgD0EJUBhBCZCHoAQojKAEyENQAhRGUALkISgBCiMoAfIQlACFEZQAeQhKgMIISoA8BCVAYQQlQB6CEqAwghIgD0EJUBhBCZCHoAQojKAEyENQAhRGUALkISgBCiMoAfIQlACFEZQAeQhKgMIISoA8BCVAYQQlQB6CEqAwghIgD0EJUBhBCZCHoAQojKAEyENQAhRGUALkISgBCiMoAfIQlACFEZQAeQhKgMIISoA8BCVAYQQlQB6CEqAwghIgD0EJUBhBCZCHoAQojKAEyENQAhRGUALkISgBCiMoAfIQlACFEZQAedSp8++7yKqqqoyXAJQ2QQmQhyOUAIURlAB5CEqAwghKgDwEJUBhBCVAHoISoDCCEiAPQQlQGEEJkIegBCiMoATIQ1ACFEZQAuQhKAEKIygB8hCUAIURlAB5CEqAwghKgDwEJUBhBCVAHoISoDCCEiAPQQlQGEEJkIegBCiMoATIQ1ACFEZQAuQhKAEKIygB8hCUAIURlAB5CEqAwghKgDwEJUBhBCVAHoISoDCCEiCFoARIJigBEpSVlQlKgBSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEghKgHSCEiCBoARIJygBEtSpU0dQAqQQlAAJysrKoqqqKusZACVNUAIkcMobIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEggKAHSCUqABIISIJ2gBEhQp04dQQmQQlACJCgrK4uqqqqsZwCUNEEJkMApb4B0ghIggaAESCcoARIISoB0ghIggaAESCcoARIISoB0ghIggaAESCcoARIISoB0ghIggaAESCcoARIISoB0ghIggaAESCcoARIISoB0ghIggaAESCcoARIISoB0ghIggaAESCcoARIISoB0ghIggaAESCcoARIISoB0ghIggaAESCcoARKUlZVlPQGg5AlKgARrg9JRSoD8BCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAAkEJkE5QAiQQlADpBCVAHmuqVkbjr7waoyeeGavj+aiqWpX1JICSVJbztBvgc6qqVsWCt2bFpyvfiaqqqqhbp040arh7lO96YZSVeS4OsD73igAb8dEnc2PlZ+9EWVlE3bp1IsoiVqx8PZZ/+lrW0wBKjqAE2IglS97a6O3Lli3ewksASp+gBFjPwoUL4+KLL46TTjwvVq1aE2tfFFRVlYsVK1bFd4/8SfTu3TsWLxaWAGsJSoCIWLBgQbRr1y722WefuOuuu+KS9r1i16anR906DSIion69rWO3pq3jwgs6xMyZM6O8vFxYAvwf/ykHqNVeeeWVGDZsWMyePTuaNm0affv2jUsuuSQaN24cEf++XNCaqhVRt06jdZcQWrZsWUyYMCEmTJgQq1evjo4dO0afPn1i5513zvJHAciMoARqpXnz5sWwYcNizpw50axZs+jXr19cfPHFsfXWWxf8NTYMy06dOkWfPn1ip5122ozLAUqPoARqlblz50ZlZWXccMMNsfPOO0f//v2jffv20ahRoy/9NZctWxbjx4+PiRMnCkugVhKUQK3w0ksvRWVlZdx0003RvHnz6N+/f7Rr1y4aNmy4yb7H+mG5Zs2adafChSVQ0wlKoEZ74YUXorKyMm6++ebYbbfdYsCAAfGLX/xik4bkhoQlUNsISqBG+uc//xmXX3553HrrrfHVr341Kioq4qKLLooGDRpssQ0bhmWnTp2id+/ewhKocQQlUKM8//zzMXTo0Ljttttijz32iIqKirjwwgtjq622ymzTu+++G+PHj49JkyYJS6BGEpRAjfDcc8/F0KFD44477oiWLVvGwIED4/zzz880JDe0NiwnTpwYVVVVwhKoMQQlUK09++yzMXTo0Ljrrrtizz33jIEDB8Z5550X9evXz3paXhuGZefOnaN3797RrFmzrKcBfCmCEqiWnnnmmRgyZEjcc889sddee8WgQYPinHPOKemQ3JCwBGoKQQlUK3/7299iyJAhce+998Y+++wTgwYNirPPPjvq1auX9bQv7d13341x48bFpEmThCVQLQlKoFr461//GkOGDIn77rsvWrVqFYMGDYqzzjqrWofkhoQlUF0JSqCk/eUvf4khQ4bE/fffH/vtt18MHjw42rRpE3Xr1s162mazfljmcrno3Llz9OrVS1gCJUtQAiXpiSeeiCFDhsSDDz4YBxxwQAwePDhat25do0NyQ0uXLo1x48bF5MmThSVQ0gQlUFIee+yxGDJkSDz00ENx4IEHxqWXXhpnnHFG1KlTJ+tpmRGWQKmrvffQQEl59NFH47jjjoujjjoq3nnnnbjtttviueeei9atW9fqmIyIaNq0aQwfPjxeffXV6Nq1a0ydOjXKy8ujf//+sXTp0qznAQhKIFuPPPJIHHvssXH00UfHsmXL4o477ohnn3221h+V3JgNw3LKlCnRsmXLGDBggLAEMuXeGtjicrlcPPzww3H00UfHscceGx988EHcdddd8cwzz8Rpp50mJFOsDcuFCxdGly5dYvLkycISyJR7bWCLyeVy8dBDD8X3vve9OO6442L58uVxzz33xNNPPx2nnnpqlJWVZT2xWmnatGlcccUVwhLInKAENrtcLhcPPvhgfPe7340f/OAHsXLlyrj33nvjqaeeilNOOUVIFmljYVleXh4VFRXCEtgiBCWw2eRyubj//vvjyCOPjBNPPDHWrFkT9913Xzz55JNx8sknC8lNbP2w7Ny5c0yaNElYAluEoAQ2uVwuF/fdd198+9vfjh/+8IdRVlYW999/f/z5z39e9zGbz9qwfPXVV6NTp07CEtjsBCWwyeRyubj33nvj8MMPj5NPPjnq168fDz74YDz++ONx4oknCsktrFmzZjFixIiNhuW7776b9TygBhGUQNFyuVzcfffdcdhhh8Upp5wSjRo1ioceeij+9Kc/xQ9+8AMhmbGNhWXLli1j4MCBwhLYJAQl8KVVVVXFnXfeGd/85jfjpz/9aWy77bbx8MMPxx//+Mc47rjjhGSJ2TAsJ06cKCyBTUJQAl9YVVVV3H777XHIIYfE6aefHk2aNIlHHnlk3UXKhWRpWz8sO3bsGBMmTBCWQFEEJVCwqqqquPXWW+Pggw+OM888M5o1axaPPvrououUU700a9YsRo4cGQsXLhSWQFEEJZBqzZo18etf/zoOOuig+NnPfha77LJLPPbYY/HQQw/FUUcdlfU8irSxsCwvL49BgwYJS6AgZblcLpf1CKA0rVmzJm655Za4/PLL48UXX4wTTzwxLrvssvjOd76T9TQ2oyVLlsSYMWNiypQpUbdu3ejatWv07Nkzdthhh6ynASVKUAKfs2bNmrj55pujsrIyXnrppfjhD38Yl112WRxxxBFZT2MLeuedd2LMmDExdepUYQkkEpTAOqtXr46bbropKisrY+7cuXHyySfHpZdeGocffnjW08iQsATSCEogVq9eHTfccENUVlbG/Pnz45RTTolLL700DjvssKynUUI2DMtu3bpFjx49hCUgKKE2W7VqVcyZMyeGDRsWr7zySpx66qlx6aWXxje/+c2sp1HC3nnnnRg9enRMnTo16tWrJywBQQm10apVq2L27NkxbNiwePXVV+P000+PwYMHx8EHH5z1NKoRYQmsJSihFvnss8/iuuuui+HDh8fChQvjzDPPjMGDB8dBBx2U9TSqscWLF687FV6/fv3o1q1bdO/eXVhCLSIooRZYuXJlXHvttTF8+PB4/fXXo3Xr1jF48OA48MADs55GDbKxsOzRo0c0adIk62nAZiYooQZbuXJlXH311TFixIh44403ok2bNjFo0KD42te+lvU0arDFixfH6NGjY9q0acISaglBCTXQp59+GrNmzYoRI0bEokWL4qyzzopBgwbF/vvvn/U0ahFhCbWHoIQaZMWKFXHVVVfFyJEj4+23346zzz47Bg0aFK1atcp6GrXYhmHZvXv36N69u7CEGkRQQg2wYsWKmDFjRowaNSoWL14c5557bgwcODD23XffrKfBOsISai5BCdXYJ598EtOnT49Ro0bF0qVL47zzzouBAwfG3nvvnfU0yOvtt9+O0aNHx5VXXiksoYYQlFANLV++PK688soYPXp0LFu2LM4///yoqKiIvfbaK+tpUDBhCTWHoIRq5OOPP45p06bFmDFj4r333osLL7wwKioqory8POtp8KWtH5ZbbbXVurD8yle+kvU0oECCEqqBjz76KKZOnRpjx46NDz74IC666KIYMGBAtGzZMutpsMmsDctp06ZFgwYNhCVUI4ISStiHH34YU6ZMibFjx8ZHH30Ubdu2jQEDBkSLFi2yngabzdtvvx2jRo2KK6+8UlhCNSEooQR98MEHMXny5Bg3blwsX7482rVrF/3794/dd98962mwxWwYlj169Ihu3boJSyhBghJKyPvvvx+TJk2K8ePHx4oVK6J9+/bRr1+/+OpXv5r1NMiMsITSJyihBLz33nsxceLEmDBhQqxcuTIuueSS6Nu3b+y6665ZT4OSsWjRohg1alRMnz5dWEKJEZSQoWXLlsWECRNi4sSJsWrVqujQoUP06dMnmjdvnvU0KFnCEkqPoIQMvPvuuzF+/PiYNGlSrF69Ojp27Bi9e/eOXXbZJetpUG2sH5YNGzaMHj16RNeuXYUlZEBQwha0dOnSGDduXEyePDmqqqqiU6dO0bt379hpp52yngbV1sbCslu3brH99ttnPQ1qDUEJW8CSJUti7NixMWXKlIiI6Ny5c/Tq1SuaNWuW8TKoORYtWhQjR46MGTNmCEvYwgQlbEbvvPNOjBkzJqZOnRp16tSJLl26RM+ePaNp06ZZT4Maa21YTp8+PRo1aiQsYQsQlLAZrP9WcvXq1YuuXbtGjx49Yscdd8x6GtQab7311rpT4Y0aNYqePXtG165dhSVsBoISNqH1X8u11VZbRbdu3aJ79+6xww47ZD0Nai1hCZufoIRN4K233oqRI0fGzJkz171VXLdu3aJJkyZZTwP+z9rf0xkzZghL2MQEJRThzTffjBEjRsRVV1217rVaLlsCpU1YwqYnKOFLeP3112PEiBExa9asaNy4cfTs2TO6dOniAQmqkfXDcuutt/Z7DEUQlPAF/O///m9cccUVcc0118Q222wTvXr1is6dO8d2222X9TTgS9pYWHbt2tXvNXwBghIK8Nprr8Xw4cPjv//7v2O77baL3r17R6dOnWLbbbfNehqwibz55pvrXgstLOGLEZSQ4NVXX43hw4fHtddeG02aNInevXtHx44dY5tttsl6GrCZbBiWvXr1ii5dughLSCAoYSMWLFgQw4YNi9mzZ8cOO+wQffr0iV/+8pfRuHHjrKcBW4iwhMIJSljP/PnzY9iwYXH99ddH06ZNo2/fvtGhQ4fYeuuts54GZERYQjpBCRExb968qKysjBtuuCGaNWsW/fr1i4svvlhIAuusvUzYzJkzo3HjxsIS1iMoqdVefvnlqKysjBtvvDF22WWX6NevX7Rv3z4aNWqU9TSgRL3xxhvrjli62gP8m6CkVnrxxRejsrIybr755mjevHn0798/2rVrFw0bNsx6GlBNCEv4/wQltcoLL7wQl19+efz617+O3XbbLQYMGBBt27aNBg0aZD0NqKbeeOONde+YJSyprQQltcI///nPGDp0aNx2222x++67R0VFRVx44YVCEthkNhaWXbp0cb1aagVBSY32j3/8I4YOHRq33357tGzZMioqKuKCCy6IrbbaKutpQA21YVj27t07OnfuLCyp0QQlNdLf//73GDp0aNx5551RXl4eAwcOjPPPPz/q16+f9TSglhCW1CaCkhrl2WefjSFDhsTdd98de+21VwwcODDOPfdcIQlk5vXXX48RI0bErFmzhCU1lqCkRnj66adjyJAh8Zvf/Cb23nvvGDRoUJxzzjlRr169rKcBRISwpGark/UAKMZTTz0VP/7xj+Owww6Ll19+OWbPnh0vvvhiXHDBBWISKCm77757TJ06NebPnx9nnXVW/OpXv4ry8vIYMWJEfPTRR1nPg6IISqqlJ598Mn70ox/F4YcfHvPnz485c+bECy+8EOedd56QBEra+mHZpk2buOyyy4Ql1Z6gpFr585//HCeddFJ8+9vfjoULF8aNN94Y//rXv+Kcc86JunXrZj0PoGDrh+XPfvazuPTSS4Ul1ZagpFp4/PHH44QTTogjjzwy3njjjbj55pvj+eefj5///OdCEqjWdt9995g2bVq88sor/xGWI0eOjI8//jjreVAQQUlJ+9Of/hTHH398fPe7341FixbFLbfcEv/4xz+iTZs2QhKoUdaG5dojloMHD46WLVsKS6oFQUlJ+uMf/xjf//7343vf+14sWbIkbrvttnjuueeidevWUaeOf7ZAzdWiRQthSbXjkZmSkcvl4g9/+EMcc8wxccwxx8R7770Xd9xxRzz77LNxxhlnCEmgVlk/LFu3bi0sKWkeoclcLpeL3//+93H00UfH97///fjwww/jrrvuimeeeSZOO+00IQnUai1atIgrr7zyP8KyvLw8Ro0aJSwpGR6pyUwul4vf/e53cdRRR8Xxxx8fn3zySdxzzz3x9NNPx6mnnhplZWVZTwQoGeuH5ZlnnhmDBg0SlpQMQckWl8vl4oEHHoj/+q//ihNOOCE+++yzuPfee+Opp56KU045RUgCJFgblvPmzYszzjhDWFISBCVbTC6Xi//5n/+J73znO3HSSSet+/jJJ5+Mk08+WUgCfAF77LFHTJ8+XVhSEgQlm10ul4vf/va3ccQRR8SPfvSjqFu3bjzwwAPxxBNPxEknnSQkAYqQLyxHjx4dy5cvz3oetYSgZLPJ5XJxzz33xLe+9a348Y9/HA0aNIjf/e538dhjj8UJJ5wgJAE2oQ3DcuDAgdGyZUthyRYhKNnkcrlc3HXXXXHooYfGqaeeGo0bN47f//738eijj8bxxx8vJAE2o/XD8vTTT4+KigpHLNnsBCWbTFVVVdxxxx1xyCGHxGmnnRbbbbdd/OEPf1h3kXIhCbDl7LHHHjFjxoyYP39+nHbaaevCcsyYMcKSTU5QUrSqqqq47bbb4pBDDokzzjgjdthhh3jkkUfikUceiWOOOSbreQC12tqwnDdvXpx22mkxYMAAYckmJyj50qqqquKWW26Jb3zjG9G6devYaaed4tFHH42HH344jj766KznAbCeli1bCks2G0HJF7ZmzZq4+eab4+tf/3q0adMmdt1113j88cfXXaQcgNK1flj+9Kc/FZZsEoKSgq1ZsyZuvPHG+PrXvx4///nPo0WLFvHEE0/EAw88EEceeWTW8wD4Alq2bBkzZ878j7Dcc889Y+zYscKSL0xQkmr16tUxZ86c+NrXvhbnnHNOlJeXx1/+8pd1FykHoPpaPyxPPfXU6N+/v7DkCxOU5LV69eqYPXt2HHDAAXHeeefFPvvsE3/961/XXaQcgJpDWFIMQcnnrF69Oq699trYf//944ILLoj9998//va3v8VvfvOb+Na3vpX1PAA2o7VhOXfu3PjJT37yH2H5ySefZD2PEiUoWWfVqlVxzTXXRKtWreKiiy6KAw88MJ555pm4++6749BDD816HgBbUHl5eVx11VX/EZbl5eUxbtw4YcnnCEris88+i1mzZkWrVq2ibdu2cfDBB8ff//73uPPOO+OQQw7Jeh4AGdowLPv16ycs+RxBWYt99tlnMXPmzNh3332jffv2ceihh8Zzzz0Xt99+e3zjG9/Ieh4AJWRtWL788stxyimnCEv+g6CshVauXBlXXnll7L333tGhQ4c44ogj4vnnn49bb701DjrooKznAVDC9txzz5g1a9a6sOzbt6+wJMpyuVwu6xFsGZ9++mlcffXVMWLEiHjzzTejTZs2MXjw4DjggAOyngZANbVgwYIYPnx4XHvttdG0adPo169fXHLJJbH11ltnPY0tSFDWAp9++mlcddVVMXLkyFi0aFGcddZZMWjQoNh///2zngZADSEsazdBWYOtWLEiZs6cGSNHjozFixfH2WefHYMGDYpWrVplPQ2AGmrBggUxbNiwuO6664RlLSIoa6BPPvkkZsyYEaNGjYolS5bEueeeGxUVFbHvvvtmPQ2AWmL9sGzWrNm6sGzUqFHW09gMBGUNsnz58pg+fXqMHj06li5dGueff35UVFTE3nvvnfU0AGopYVk7CMoaYPny5TFt2rQYM2ZMLFu2LC644IKoqKiIPffcM+tpABARwrKmE5TV2McffxxTp06NMWPGxPvvvx8XXXRRDBgwIMrLy7OeBgAb9corr8SwYcNi9uzZwrIGEZTV0EcffRRTpkyJsWPHxocffhi/+MUvYsCAAbHHHntkPQ0ACrJhWPbv3z8uvvhiYVlNCcpq5MMPP4zJkyfHuHHj4uOPP462bdtG//79o0WLFllPA4AvRVjWDIKyGvjggw9i0qRJMX78+Fi+fHm0b98++vXrF7vvvnvW0wBgkxCW1ZugLGHvv/9+TJw4MSZMmBArVqyIiy++OPr16xe77bZb1tMAYLOYP39+DBs2LK6//nphWY0IyhL03nvvxYQJE2LixImxcuXKuOSSS6Jv376x6667Zj0NALaI9cNyp512iv79+0f79u2FZYkSlCVk2bJlMX78+Jg0aVKsWrUqOnToEH369InmzZtnPQ0AMiEsqwdBWQLefffdGDduXEyePDlWr14dHTt2jD59+sTOO++c9TQAKAnCsrQJygwtXbo0xo4dG1OmTImqqqro1KlT9O7dO3baaaespwFASZo/f35UVlbG9ddfHzvvvHMMGDAg2rdvHw0bNsx6Wq0mKDOwZMmSGDNmTEydOjUiIjp37hy9evWKZs2aZbwMAKqHefPmrTtiKSyzJyi3oMWLF8eYMWNi2rRpUadOnejSpUv07NkzmjZtmvU0AKiW1g/LXXbZZd2pcGG5ZQnKLeDtt9+OUaNGxfTp06NevXrRtWvX6NGjR+y4445ZTwOAGmHevHlRWVkZc+bMEZYZEJSb0aJFi2LkyJExY8aM2GqrraJ79+7RvXv3aNKkSdbTAKBG2jAsBwwYEO3atROWm5mg3AzefPPNGDlyZMycOTMaNmwY3bt3j27duglJANhChOWWJSg3oTfeeCNGjBgRs2bNikaNGkWPHj2ia9eu8ZWvfCXraQBQKwnLLUNQbgKvv/56XHHFFXH11VdH48aNo2fPntGlS5fYfvvts54GAETE3Llzo7KyMm644QZhuRkIyiK89tprccUVV8Q111wT2267bfTq1Ss6d+4c2223XdbTAICNWD8smzdvHgMGDIi2bdsKyyIJyi9h4cKFMXz48Lj22mtj++23j969e0fHjh1j2223zXoaAFAAYblpCcovYMGCBTF8+PC47rrrokmTJtGnT5/45S9/Gdtss03W0wCAL0FYbhqCsgCvvPJKDBs2LGbPnh077rhj9O3bNzp06BCNGzfOehoAsAm8/PLLUVlZGTfeeKOw/BIEZYK1V9+fM2dONGvWLPr27RuXXHJJbL311llPAwA2gw3DsqKiItq2bRsNGjTIelpJq5P1gKx98HrEqw9HvPfq/79t7ty5cf7558d+++0XDz74YIwdOzYWLFgQPXr0EJMAUIO1atUqrr/++njhhRfi2GOPjS5dusRee+0V06ZNi5UrV2Y9r2TV6iOUT8+M+O0vI3JVEVEWcVDPd+L2t3vGTTfdtO5tm9q1axeNGjXKeioAkIH1j1juuuuu606FN6hbN2L27IhXXok44ICIn/88ok7tPU5Xa4Py3bkRU/aLiA1++rua/TjaXfZDr5sAANZ56aWXorKyMm666ab4avPm8aftt4/dX3wxyurVi1i16t9BecMNEWVlWU/NRK0Nyhdui7i19edvP2nKqjiiU/0tPwgAKHkvvfRS/LZDh+j1xz9+/pNPPBHxne9s+VEloNYem92+xcZv32FPMQkAbNx+++0Xvc4+e+OffOutLTumhNTaoNz1WxHfbP/vv5fV/fef+58RsfeJ2W0CAKqBww77/KntevUiDj44kzmloNae8o6IyOUi5v4m4p1/Reywd8QBZ0SU1drEBgAKNmVKRLduEVVVEfXrR1x9dcR552W9KjO1OigBAL60xYsjXnstYs89I5o2zXpNpgQlAABFcYIXAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKIqgBACgKIISAICiCEoAAIoiKAEAKMr/A+S820ncsX6FAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "circuit = QuantumCircuit.from_qasm_file(\"data/ghz_circuit.qasm\")\n", - "\n", - "clifford_t_circuit = pyliqtr_transpile_to_clifford_t(circuit, circuit_precision=1e-10)\n", - "circuit_graph = get_algorithmic_graph_from_Jabalizer(clifford_t_circuit)\n", - "compiler = substrate_scheduler(circuit_graph, \"fast\")\n", - "\n", - "plot_graph_state_with_measurement_steps(\n", - " compiler.input_graph, compiler.measurement_steps\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "update_tableau: \tcurrent_inverse_tableau: 0.002491 seconds (3 allocations: 72 bytes)\n", - "\tinverse: 0.283423 seconds (4 allocations: 72 bytes)\n", - "\tupdate stabilizers: \n", - "\t3208:\t0.19s, elapsed time: 0.0 min\n", - " 0.190625 seconds (231.00 k allocations: 11.141 MiB)\n", - " 0.476994 seconds (231.09 k allocations: 11.146 MiB)\n", - "\tsort!: 0.274480 seconds (2 allocations: 25.109 KiB)\n", - "\tMake X-block upper triangular: 0.036588 seconds (1 allocation: 144 bytes)\n", - "\tMake diagonal: 0.023012 seconds\n", - "\tPhase correction and checks: 0.000225 seconds (4 allocations: 43.094 KiB)\n", - "\tCheck symmetry: 0.041304 seconds\n", - "starting substrate scheduler\n", - "substrate scheduler took 0.00705409049987793 seconds\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "circuit = QuantumCircuit.from_qasm_file(\"data/h_chain_circuit.qasm\")\n", - "\n", - "\n", - "clifford_t_circuit = pyliqtr_transpile_to_clifford_t(circuit, circuit_precision=1e-10)\n", - "circuit_graph = get_algorithmic_graph_from_Jabalizer(clifford_t_circuit)\n", - "compiler = substrate_scheduler(circuit_graph, \"fast\")\n", - "\n", - "plot_graph_state_with_measurement_steps(\n", - " compiler.input_graph, compiler.measurement_steps\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Closing Statements\n", - "\n", - "### What did we learn?\n", - "\n", - "\n", - "#### Inputs\n", - "- Circuit\n", - "- Architecture model\n", - "#### Outputs\n", - "- Number of physical qubits\n", - "- Computation time\n", - "- Number of measurement steps\n", - "\n", - "\n", - "\n", - "#### Components:\n", - "- Transpilation (pyliqtr)\n", - " - Bring to Clifford + T\n", - "- Jabalizer/ICM\n", - " - Easy way to represent circuit\n", - "- Min code distance finding\n", - " - Number of physical qubits\n", - " - Computation time\n", - "- Substrate scheduling\n", - " - number of measurement steps" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## What's Next?\n", - "\n", - "- How to get resource estimate for large algorithms? (QuantumPrograms)\n", - "- Compare to other resource estimators.\n", - "- Try this notebook out for yourself!!" - ] + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Toy Problem Demo\n", + "\n", + "## Scope\n", + "\n", + "Overview of Benchq:\n", + "- inputs and outputs\n", + "- components:\n", + " - Transpilation (pyliqtr)\n", + " - Jabalizer/ICM\n", + " - Min code distance finding\n", + " - Substrate scheduling\n", + "\n", + "\n", + "Wait a little for TA 1 and TA 1.5\n", + "\n", + "### Goal: Introduction to Benchq Tool for Resource Estimation" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Agenda\n", + "- Quick overview of Benchq usage.\n", + "- What is a circuit graph? How do we produce them?\n", + "- How do circuit graphs help get resource estimates?\n", + "- Look at some pretty plots\n", + " - Preparing a GHZ state\n", + " - The fully connected graph" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Introduction to Graph Estimators\n", + "\n", + "Let's go through a gory example of what benchq is doing for the case of a graph resource estimator.\n", + "\n", + "First we need to import some things and install a python environment in your python installation. This might take a minute.\n", + "\n", + "Running this line will install julia to your python installation. See README for details." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "from qiskit import QuantumCircuit\n", + "import networkx as nx\n", + "\n", + "\n", + "from benchq.compilation.circuits import pyliqtr_transpile_to_clifford_t\n", + "from benchq.compilation.graph_states import get_jabalizer_circuit_compiler, get_ruby_slippers_circuit_compiler\n", + "from benchq.resource_estimators.graph_estimator import (\n", + " GraphResourceEstimator,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from benchq.quantum_hardware_modeling import BASIC_SC_ARCHITECTURE_MODEL\n", + "\n", + "demo_circuit = QuantumCircuit.from_qasm_file(\"data/single_rotation.qasm\")\n", + "architecture_model = BASIC_SC_ARCHITECTURE_MODEL" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, transpile into Clifford + T." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Circuit(operations=[H(0), Z(0), H(0), S†(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), H(0)], n_qubits=1)\n" + ] } - ], - "metadata": { - "kernelspec": { - "display_name": "benchq-demo-3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - }, - "orig_nbformat": 4, - "vscode": { - "interpreter": { - "hash": "fbda94f5ddcb73da906661b05314820b4a1597f16c608ce3a58aaa500dc8b85a" - } + ], + "source": [ + "clifford_t_circuit = pyliqtr_transpile_to_clifford_t(\n", + " demo_circuit, circuit_precision=1e-2\n", + ")\n", + "print(clifford_t_circuit)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Transform circuit into compiled data representing the time and space required to make the graph." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "GSCInfo(num_logical_qubits=4, num_layers=22, graph_creation_tocks_per_layer=[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], t_states_per_layer=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0], rotations_per_layer=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" } + ], + "source": [ + "optimization = \"Time\" # or \"Space\"\n", + "verbose = False\n", + "compiler = get_ruby_slippers_circuit_compiler()\n", + "compiler(clifford_t_circuit, optimization, verbose)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnYAAAHWCAYAAAD6oMSKAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdeXwU9f348dfsfSSbzZ0AgYQrAhogChoVRQGjoBRDQamoKFgqtNGi0tKfCFpbW6v1QixfULBi5QtKIyqKwBcsWC6RCHIEhIAcua9NNtlsdnd+fyy7MuzmJCEJfJ6PRx6aec98ZnYyzL7nM59DkmVZRhAEQRAEQej0VO19AIIgCIIgCELrEImdIAiCIAjCJUIkdoIgCIIgCJcIkdgJgiAIgiBcIkRiJwiCIAiCcIkQiZ0gCIIgCMIlQiR2giAIgiAIlwiR2AmCIAiCIFwiRGInCIIgCIJwiRCJndAmjh8/jiRJvPTSS+19KIIgCK1m2bJlSJLE8ePH/cuGDx/O8OHD26x8QWgOkdh1crm5ufz617+mb9++mEwmTCYT/fv3Z+bMmezdu7e9D++CHD9+nIceeohevXphMBiIi4vjpptuYt68eYr1Fi5cyLJly1q8nzNnzjB//nyys7Mv7IAFQbhofAmQ78dgMNC3b19+/etfU1BQ0N6HF1RiYqLimM/9cTgc7X14wiVC094HILTcp59+yj333INGo+G+++5j4MCBqFQqDh06xOrVq3nrrbfIzc2lR48e7X2ozfbDDz8wZMgQjEYjDz/8MImJieTl5fHtt9/y17/+lWeffda/7sKFC4mKimLKlCkt2teZM2d49tlnSUxMZNCgQa3zAQRBuCiee+45kpKScDgcbN26lbfeeou1a9fy/fffYzKZLsoxfPnll01ed9CgQTzxxBMBy3U6XWseknAZE4ldJ3X06FHuvfdeevTowcaNG4mPj1fE//rXv7Jw4UJUqoYrZe12O2azuS0PtUVeeeUVqqqqyM7ODkhMCwsL2+moBEHoaO644w6uueYaAKZNm0ZkZCR///vf+fjjj5k0adJFOYbmJGVdu3Zl8uTJbXg0wuVOvIrtpF588UXsdjtLly4NSOoANBoNmZmZJCQk+JdNmTKFkJAQjh49yujRowkNDeW+++4DYMuWLUyYMIHu3buj1+tJSEjgt7/9LTU1NYpyfWUcO3aM9PR0zGYzXbp04bnnnkOW5aDH+j//8z/06tULvV7PkCFD2LVrV6Of7+jRo3Tr1i1obWNMTIz//xMTE9m/fz9fffWV/5WGr61LaWkpTz75JFdddRUhISFYLBbuuOMOvvvuO//2mzdvZsiQIQA89NBD/jLOfbW7Y8cObr/9dsLCwjCZTNx88818/fXXjX4GQRAuvltvvRXwNlMBeOmll7j++uuJjIzEaDRy9dVX8+GHHyq28bUJDtakQ5Ik5s+f3+A+W7ONXX0WLlzIgAED0Ov1dOnShZkzZ1JeXu6Pv/7666jVasWyl19+GUmSmDVrln+Z2+0mNDSU3/3ud216vEL7ETV2ndSnn35K7969ufbaa5u1ncvlIj09nRtvvJGXXnrJ/6pi1apVVFdX8+ijjxIZGcnOnTt54403OHXqFKtWrVKU4Xa7uf3227nuuut48cUX+eKLL5g3bx4ul4vnnntOse6//vUvKisrmT59OpIk8eKLL5KRkcGxY8fQarX1HmePHj3YsGED//d//+e/UQfz6quv8pvf/IaQkBD+3//7fwDExsYCcOzYMbKyspgwYQJJSUkUFBSwaNEibr75Zg4cOECXLl3o168fzz33HM888wy//OUvGTZsGADXX389AP/3f//HHXfcwdVXX828efNQqVQsXbqUW2+9lS1btjB06NBmnX9BENrW0aNHAYiMjATgtddeY+zYsdx33304nU5WrFjBhAkT+PTTTxkzZsxFP766ujqKi4sVy3zto+szf/58nn32WUaOHMmjjz5KTk4Ob731Frt27eLrr79Gq9UybNgwPB4PW7du5c477wS8D+wqlYotW7b4y9qzZw9VVVXcdNNNbfMBhfYnC51ORUWFDMjjxo0LiJWVlclFRUX+n+rqan/swQcflAH597//fcB2567n88ILL8iSJMknTpwIKOM3v/mNf5nH45HHjBkj63Q6uaioSJZlWc7NzZUBOTIyUi4tLfWv+/HHH8uA/MknnzT4Gb///nvZaDTKgDxo0CD5sccek7OysmS73R6w7oABA+Sbb745YLnD4ZDdbrdiWW5urqzX6+XnnnvOv2zXrl0yIC9dulSxrsfjkfv06SOnp6fLHo/Hv7y6ulpOSkqSR40a1eBnEASh7SxdulQG5A0bNshFRUXyyZMn5RUrVsiRkZGy0WiUT506Jcty4L3N6XTKV155pXzrrbf6l/nuV+ffA2RZlgF53rx5AfvNzc31L7v55puD3oPO16NHDxkI+Gmo/MLCQlmn08m33Xab4n62YMECGZDfeecdWZZl2e12yxaLRZ49e7Ysy977V2RkpDxhwgRZrVbLlZWVsizL8t///ndZpVLJZWVljR6v0DmJV7GdkM1mAyAkJCQgNnz4cKKjo/0/b775ZsA6jz76aMAyo9Ho/3+73U5xcTHXX389siyzZ8+egPV//etf+/9fkiR+/etf43Q62bBhg2K9e+65h/DwcP/vvhqxY8eONfgZBwwYQHZ2NpMnT+b48eO89tprjBs3jtjYWBYvXtzgtj56vd7fxtDtdlNSUkJISAjJycl8++23jW6fnZ3NkSNH+MUvfkFJSQnFxcUUFxdjt9sZMWIE//nPf/B4PE06FkEQ2sbIkSOJjo4mISGBe++9l5CQEP7973/TtWtXQHlvKysro6KigmHDhjXpHtAWrr32WtavX6/4eeCBB+pdf8OGDTidTh5//HFFm+lHHnkEi8XCZ599BoBKpeL666/nP//5DwAHDx6kpKSE3//+98iyzLZt2wBvLd6VV16J1Wptuw8ptCvxKrYTCg0NBaCqqiogtmjRIiorKykoKAjaQFej0dCtW7eA5T/++CPPPPMMa9asoaysTBGrqKhQ/K5SqejZs6diWd++fQECxl7q3r274ndfknf+PoLp27cv7733Hm63mwMHDvDpp5/y4osv8stf/pKkpCRGjhzZ4PYej4fXXnuNhQsXkpubi9vt9sd8r2kacuTIEQAefPDBetepqKhQJK6CIFxcb775Jn379kWj0RAbG0tycrIiAfr00095/vnnyc7Opra21r9ckqT2OFyioqIavXed68SJEwAkJycrlut0Onr27OmPg/fBef78+dTU1LBlyxbi4+NJTU1l4MCBbNmyhVGjRrF161YmTpzYOh9G6JBEYtcJhYWFER8fz/fffx8Q87W5q29wy3NrsXzcbjejRo2itLSU3/3ud1xxxRWYzWZOnz7NlClTLqhWSq1WB10u19PRor4yrrrqKq666irS0tK45ZZbeP/99xu9Of75z39m7ty5PPzww/zxj38kIiIClUrF448/3qTP5Fvnb3/7W73DoASrNRUE4eIZOnSov1fs+bZs2cLYsWO56aabWLhwIfHx8Wi1WpYuXcq//vUv/3r1JXnn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6dKlS8jj1YKCAtxuN9deey1JSUn07NmT8vJyGRXZTiiKQmZmJgMGDOC7774jNzeX8vJyPB4PRqORnj17MnDgwHP2odPpdIwZM4bRo0fz9ddf87vf/Y7Jkyfz4osvMnXqVB5//HEqKytDOlufy8qVKxtXuDiz301bV089G9hACSUoKCSRxI3cqFpyz+fz8eijj/LRRx/x8ccfM3bs2Fassbjc3li9r0XLf/2rvTLliRDNrM0ndn//+985fPhwk8sX7dy5E4Brr70WjUaDy+Xi448/5rHHHsNkkqVq2gu9Xk///v1VrWkXQ1EUfvjDH/LDH/6Q77//nj/84Q/85je/4bXXXuOZZ5457/nvamtr8fl8OBwOHn30USAwMqstCtd/8Mfzfsw3E76hnNM6a08A5ocvY8GCBdIS3gHtL645905tuHwhOqI2ndgVFxfz3XffNRn3er3k5eWRkpJCTExgviS/309VVRVbt24lM/PcM5+LjqtXr168/fbbvPrqq7z77rsXNCHyG2+80TgKymw28+qrr3Lbbbe1VFUvSWlpKa+++ipdu3al83WdqVhfwQpW4CfMhyUjKHMUDH4DqStS2bl4J0899ZT0We2Aihwu1TqxLcHj81PscMl6sUI0ozad2G3ZsgWNRhMyxDvo+++/p66ujvT09JDY5s2bGTJkiExRIc7JbrfTt29fdu7cedaF7U83bty4xuksdu7cyffff3/ug1pJsP/gpqRN3PPtPTCQ8EkdgA784/zU++rZ8cAOXnjkBf6/2/+/y1pf0TZsOlh27p2awcaDZYy67tKmIxJCnNJmEzuPx8O2bduaTOog8BhWo9GQlpYWEqusrKSgoKDdT0EhmkdZWdl5J3UA3bsHOpH37t2bq6++mnfffZeBAwfyi1/84pLrsW/fPmpra1EUhcjISPr27YvVar3oMo1GI74kHw9wnoMevIATlAiFt29/m+d4DhsyyrSjqWvwnnunK+g8QnQUbXZUrNPpPOujsfr6evbu3UuvXr2wWCxh9zlzskchmnLmRLEXwm6307VrVz755JPzPqampob//u//5o477sBut6MoCo8++ihvv/02q1ev5ptvvuHrr79m5cqV/O53v2Pp0qUcPnyYvn37oigKr7/++gXV8T3eo4GGc+9YC9iAKPDH+XFMdTCnZs4FnUu0D2aDtl2dR4iOos0mdufq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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from benchq.compilation.graph_states import jl\n", + "from benchq.visualization_tools.plot_graph_state import plot_graph_state\n", + "\n", + "asg, pauli_tracker, _ = jl.get_rbs_graph_state_data(clifford_t_circuit,takes_graph_input=False,gives_graph_output=False,verbose=verbose, optimization=optimization)\n", + "asg = jl.python_asg(asg)\n", + "pauli_tracker = jl.python_pauli_tracker(pauli_tracker)\n", + "\n", + "plot_graph_state(asg, pauli_tracker)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On the left, you'll see the graph state that must be prepared in order for us to sample from a state that had the rotation performed on it.\n", + "There may be an isolated node here, this is just an artifact of the decomposition of the rotation.\n", + "\n", + "On the right, you'll see the order in which each of the nodes must be measured in order to perform T gates. As expected they all must be measured one after the other, except our compiler was able to figure out that the last two can be measured simultaneously.\n", + "\n", + "With use this graph to make resource estimates." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "get_program_compilation_wf-1 is SUCCEEDED\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ResourceInfo(code_distance=11, logical_error_rate=0.01800563789423823, n_logical_qubits=30.0, n_physical_qubits=7260.0, total_time_in_seconds=0.000936, decoder_info=None, magic_state_factory_name='(15-to-1)_17,7,7', extra=, hardware_resource_info=None)\n" + ] + } + ], + "source": [ + "from benchq.resource_estimators.graph_estimator import GraphResourceEstimator\n", + "from benchq.algorithms.data_structures import (\n", + " AlgorithmImplementation,\n", + " ErrorBudget,\n", + ")\n", + "from benchq.compilation.graph_states import get_implementation_compiler\n", + "\n", + "# 1% error margin split evenly between all sources of error\n", + "budget = ErrorBudget.from_even_split(1e-2)\n", + "# Specify the circuit and the margins of error we allow in the results\n", + "implementation = AlgorithmImplementation.from_circuit(\n", + " clifford_t_circuit, budget, n_shots=1\n", + ")\n", + "\n", + "# Specify how to run the circuit\n", + "estimator = GraphResourceEstimator(optimization, verbose)\n", + "\n", + "# Modify our compiler to compile AlgorithmImplementation objects rather than just Circuits\n", + "implementation_compiler = get_implementation_compiler(compiler)\n", + "\n", + "\n", + "# run the estimator\n", + "resource_estimates = estimator.compile_and_estimate(\n", + " implementation, implementation_compiler, architecture_model\n", + ")\n", + "print(resource_estimates)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Summary\n", + "\n", + "#### Minimal Inputs:\n", + "- Circuit\n", + "- Archetecture Model\n", + "\n", + "#### Outputs:\n", + "- Number of physical qubits\n", + "- Computation time\n", + "- number of measurement steps (will be important later on!)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Pipelines\n", + "\n", + "#### Example usage\n", + "\n", + "Typically, one would use a pipeline to combine all these steps into one command that benchq can follow.\n", + "\n", + "Here we use one of the pre-configured pipelines called `get_precise_graph_estimate`." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ResourceInfo(code_distance=11, logical_error_rate=0.016815413530120026, n_logical_qubits=24.0, n_physical_qubits=5808.0, total_time_in_seconds=0.0010919999999999999, decoder_info=None, magic_state_factory_name='(15-to-1)_17,7,7', extra=, hardware_resource_info=None)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "get_program_compilation_wf-1 is SUCCEEDED\n" + ] + } + ], + "source": [ + "from benchq.resource_estimators.default_estimators import (\n", + " get_precise_graph_estimate,\n", + ")\n", + "\n", + "# only allow a failure to occur 1% of the time\n", + "budget = ErrorBudget.from_even_split(1e-2)\n", + "implementation = AlgorithmImplementation.from_circuit(demo_circuit, budget, 1)\n", + "optimization = \"Time\"\n", + "resource_estimate = get_precise_graph_estimate(implementation, architecture_model, optimization)\n", + "\n", + "print(resource_estimate)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Default Pipelines\n", + "Benchq offers 5 default pipelines:\n", + "\n", + "1. `get_precise_graph_estimate` - This pipeline uses the most accurate methods for estimating the resources required to run a circuit on a given architecture. It is also the slowest.\n", + "2. `get_fast_graph_estimate` - This pipeline uses faster methods for estimating the resources required to run a circuit on a given architecture. It is also less accurate.\n", + "3. `get_precise_extrapolation_estimate` - This pipeline uses the most accurate methods for estimating the resources required to get part of the graph. It will then extrapolate out to the size of the full graph.\n", + "4. `get_fast_extrapolation_estimate` - This pipeline uses the fastest methods for estimating the resources required to get part of the graph. It will then extrapolate out to the size of the full graph.\n", + "5. `get_footprint_estimate` - This pipeline is the fastest estimate, but is also the least accurate. It counts the number of T gates in the circuit and gets a space optimized estimate from that.\n", + "\n", + "They can be imported with the following command:\n", + "\n", + "```python\n", + "import benchq.resource_estimators.default_estimators import \n", + "```\n", + "\n", + "And run with the same inputs as above." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What is a a Circuit Graph?" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Compiling using Jabalizer...\n", + "Converting to Jabalizer Circuit...\n", + "Compiling to Algorithm Specific Graph...\n", + "Ordering non-clifford measurements...\n", + "Calculating number of logical qubits...\n", + "100% (23) completed in 0.0s\n", + "Running substrate scheduler...\n", + "Scheduling Clifford operations...\n", + "100% (24) completed in 0.0s\n", + "num_tocks_for_graph_creation: 24\n" + ] + } + ], + "source": [ + "this_compiled_circuit_data = compiler(clifford_t_circuit, optimization=\"Time\", verbose=True)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### What does this do?\n", + "\n", + "Recall that our circuit is in clifford + T form\n", + "\n", + "- Replaces T gates with magic measurements and ancilla\n", + "- Use stabilizer simulator efficiently to push single qubit cliffords to one side\n", + "- Now we have a circuit of the form Initialization, CNOT, Measurement (ICM form)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Circuit(operations=[H(0), Z(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), T(0), H(0), S(0), T(0), H(0), T(0), H(0), H(0)], n_qubits=1)\n" + ] + } + ], + "source": [ + "print(clifford_t_circuit)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Circuit(operations=[H(0), Z(0), CNOT(0,1), H(1), S(1), CNOT(1,2), H(2), S(2), CNOT(2,3), H(3), S(3), CNOT(3,4), H(4), S(4), CNOT(4,5), H(5), CNOT(5,6), H(6), S(6), CNOT(6,7), H(7), CNOT(7,8), H(8), S(8), CNOT(8,9), H(9), CNOT(9,10), H(10), CNOT(10,11), H(11), CNOT(11,12), H(12), CNOT(12,13), H(13), CNOT(13,14), H(14), CNOT(14,15), H(15), S(15), CNOT(15,16), H(16), CNOT(16,17), H(17), S(17), CNOT(17,18), H(18), CNOT(18,19), H(19), CNOT(19,20), H(20), S(20), CNOT(20,21), H(21), CNOT(21,22), H(22), H(22)], n_qubits=23)\n" + ] + } + ], + "source": [ + "import data.get_icm as icm\n", + "\n", + "circuit_after_icm = icm.get_icm(clifford_t_circuit)\n", + "print(circuit_after_icm)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The middle CNOTS are the interesting part:\n", + "\n", + "- The CNOTS make a graph state\n", + "- Use stabilizer simulator to find graph state (Jabalizer)\n", + "- Return the resources required to make that graph state\n", + "\n", + "(note there are a few long nodes because of a quirk in how we decomposed the rotation)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnYAAAHWCAYAAAD6oMSKAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdeXwU9f348dde2SvZ3CEBAuGMHEYMckRFowhR0FRjQVFUFCyKNloULH5V0Nparbb1wlJRQFH8gdIISkWkUMEGQQS5I3Kj5L6PTfaY3x9xV4bdXJCb97OPPGrmPfOZz06G2fd8Zj6fj0ZRFAUhhBBCCNHhadu6AkIIIYQQonlIYieEEEII0UlIYieEEEII0UlIYieEEEII0UlIYieEEEII0UlIYieEEEII0UlIYieEEEII0UlIYieEEEII0UlIYieEEEII0UlIYidaxNGjR9FoNLz44ottXRUhhGg2ixcvRqPRcPToUe+y5ORkkpOTW6x8IZpCErsO7siRIzz44IP0798fi8WCxWJh4MCBPPDAA+zatautq3dOjh49yt13302fPn0wmUxER0dzxRVXMHfuXNV68+fPZ/HixWe9n59++ol58+axc+fOc6uwEKLVeBIgz4/JZKJ///48+OCD5OTktHX1/IqLi1PV+fQfu93e1tUTnYS+rSsgzt4nn3zCLbfcgl6v5/bbb+eiiy5Cq9Vy4MABVq5cyRtvvMGRI0fo2bNnW1e1yX744QeGDRuG2WzmnnvuIS4ujlOnTvHtt9/y/PPP8/TTT3vXnT9/PhEREUyZMuWs9vXTTz/x9NNPExcXx5AhQ5rnAwghWsUzzzxDr169sNvtbN68mTfeeIM1a9awZ88eLBZLq9Th888/b/S6Q4YM4ZFHHvFZHhAQ0JxVEucxSew6qEOHDnHrrbfSs2dP1q9fT0xMjCr+/PPPM3/+fLTa+htlKyoqsFqtLVnVs/K3v/2N8vJydu7c6ZOY5ubmtlGthBDtzXXXXccll1wCwLRp0wgPD+evf/0rH3/8MZMmTWqVOjQlKevWrRuTJ09uwdqI8508iu2gXnjhBSoqKli0aJFPUgeg1+tJT08nNjbWu2zKlCkEBgZy6NAhxo0bR1BQELfffjsAmzZtYsKECfTo0QOj0UhsbCy/+93vqKqqUpXrKePw4cOkpKRgtVrp2rUrzzzzDIqi+K3rP//5T/r06YPRaGTYsGFs27atwc936NAhunfv7re1MSoqyvvfcXFx7N27l//+97/eRxqed10KCwt59NFHufDCCwkMDMRms3Hdddfx3XffebffuHEjw4YNA+Duu+/2lnH6o92vv/6aa6+9luDgYCwWC1deeSVfffVVg59BCNH6rr76aqD2NRWAF198kUsvvZTw8HDMZjNDhw7lww8/VG3jeSfY3ysdGo2GefPm1bvP5nzHri7z589n0KBBGI1GunbtygMPPEBxcbE3/sorr6DT6VTLXnrpJTQaDTNnzvQuc7lcBAUF8dhjj7VofUXbkRa7DuqTTz6hb9++jBgxoknbOZ1OUlJSuPzyy3nxxRe9jypWrFhBZWUl999/P+Hh4WzdupVXX32VkydPsmLFClUZLpeLa6+9lpEjR/LCCy/w2WefMXfuXJxOJ88884xq3ffff5+ysjKmT5+ORqPhhRdeIC0tjcOHD2MwGOqsZ8+ePfniiy/4z3/+471Q+/P3v/+d3/72twQGBvJ///d/AHTp0gWAw4cPk5GRwYQJE+jVqxc5OTksWLCAK6+8kn379tG1a1cGDBjAM888w1NPPcVvfvMbRo0aBcCll14KwH/+8x+uu+46hg4dyty5c9FqtSxatIirr76aTZs2MXz48CYdfyFEyzp06BAA4eHhALz88sukpqZy++23U1NTwwcffMCECRP45JNPGD9+fKvXz+FwkJ+fr1rmeT+6LvPmzePpp5/mmmuu4f777ycrK4s33niDbdu28dVXX2EwGBg1ahRut5vNmzdz/fXXA7U37Fqtlk2bNnnL2rFjB+Xl5VxxxRUt8wFF21NEh1NSUqIAyo033ugTKyoqUvLy8rw/lZWV3thdd92lAMrvf/97n+1OX8/jueeeUzQajXLs2DGfMn772996l7ndbmX8+PFKQECAkpeXpyiKohw5ckQBlPDwcKWwsNC77scff6wAyurVq+v9jHv27FHMZrMCKEOGDFEeeughJSMjQ6moqPBZd9CgQcqVV17ps9xutysul0u17MiRI4rRaFSeeeYZ77Jt27YpgLJo0SLVum63W+nXr5+SkpKiuN1u7/LKykqlV69eypgxY+r9DEKIlrNo0SIFUL744gslLy9POXHihPLBBx8o4eHhitlsVk6ePKkoiu+1raamRhk8eLBy9dVXe5d5rldnXgMURVEAZe7cuT77PXLkiHfZlVde6fcadKaePXsqgM9PfeXn5uYqAQEBytixY1XXs9dee00BlLfffltRFEVxuVyKzWZTZs+erShK7fUrPDxcmTBhgqLT6ZSysjJFURTlr3/9q6LVapWioqIG6ys6JnkU2wGVlpYCEBgY6BNLTk4mMjLS+/P666/7rHP//ff7LDObzd7/rqioID8/n0svvRRFUdixY4fP+g8++KD3vzUaDQ8++CA1NTV88cUXqvVuueUWQkNDvb97WsQOHz5c72ccNGgQO3fuZPLkyRw9epSXX36ZG2+8kS5duvDmm2/Wu62H0Wj0vmPocrkoKCggMDCQ+Ph4vv322wa337lzJwcPHuS2226joKCA/Px88vPzqaioYPTo0Xz55Ze43e5G1UUI0TKuueYaIiMjiY2N5dZbbyUwMJB//etfdOvWDVBf24qKiigpKWHUqFGNuga0hBEjRrBu3TrVz5133lnn+l988QU1NTU8/PDDqnem7733Xmw2G59++ikAWq2WSy+9lC+//BKA/fv3U1BQwO9//3sURSEzMxOobcUbPHgwISEhLfchRZuSR7EdUFBQEADl5eU+sQULFlBWVkZOTo7fF3T1ej3du3f3WX78+HGeeuopVq1aRVFRkSpWUlKi+l2r1dK7d2/Vsv79+wP4jL3Uo0cP1e+eJO/MffjTv39/3n33XVwuF/v27eOTTz7hhRde4De/+Q29evXimmuuqXd7t9vNyy+/zPz58zly5Agul8sb8zymqc/BgwcBuOuuu+pcp6SkRJW4CiFa1+uvv07//v3R6/V06dKF+Ph4VQL0ySef8Oyzz7Jz506qq6u9yzUaTVtUl4iIiAavXac7duwYAPHx8arlAQEB9O7d2xuH2hvnefPmUVVVxaZNm4iJiSExMZGLLrqITZs2MWbMGDZv3szEiROb58OIdkkSuw4oODiYmJgY9uzZ4xPzvHNX1+CWp7diebhcLsaMGUNhYSGPPfYYF1xwAVarlR9//JEpU6acU6uUTqfzu1ypo6NFXWVceOGFXHjhhSQlJXHVVVfx3nvvNXhx/NOf/sSTTz7JPffcwx/+8AfCwsLQarU8/PDDjfpMnnX+8pe/1DkMir9WUyFE6xk+fLi3V+yZNm3aRGpqKldccQXz588nJiYGg8HAokWLeP/9973r1ZXknX4z2BFcfvnlOBwOMjMz2bRpk/cJyahRo9i0aRMHDhwgLy/Pu1x0TpLYdVDjx49n4cKFbN269Zxf4N+9ezfff/89S5YsUT0SWLdund/13W43hw8f9rbSAXz//fdAbS/VluS5gJ86dcq7rK6L8ocffshVV13FW2+9pVpeXFxMREREg9v36dMHAJvN1qQ7bCFE+/DRRx9hMplYu3YtRqPRu3zRokWq9Tyt7qf3KAVUrWFtxTMyQFZWlupJSU1NDUeOHFFdm4YPH05AQACbNm1i06ZNzJo1C4ArrriCN998k/Xr13t/F52XvGPXQc2ePRuLxcI999zjd5T1praInbmNoii8/PLLdW7z2muvqdZ97bXXMBgMjB49utH7rc+mTZtwOBw+y9esWQOoH0tYrVafCzLUfq4zj8OKFSv48ccfVcs84/idWcbQoUPp06cPL774ot/H3nl5eY36LEKItqHT6dBoNKqWt6NHj5KRkaFaz2azERER4X0/zWP+/PmtUc16XXPNNQQEBPDKK6+ormdvvfUWJSUlqp69JpOJYcOGsWzZMo4fP65qsauqquKVV16hT58+fofIEp2HtNh1UP369eP9999n0qRJxMfHe2eeUBSFI0eO8P7776PVav2+T3emCy64gD59+vDoo4/y448/YrPZ+Oijj+p8D85kMvHZZ59x1113MWLECP7973/z6aef8vjjjxMZGdksn+/5559n+/btpKWlkZCQAMC3337LO++8Q1hYGA8//LB33aFDh/LGG2/w7LPP0rdvX6Kiorj66qu5/vrreeaZZ7j77ru59NJL2b17N++9957P+4F9+vQhJCSEf/zjHwQFBWG1WhkxYgS9evVi4cKFXHfddQwaNIi7776bbt268eOPP7JhwwZsNhurV69uls8rhGh+48eP569//SvXXnstt912G7m5ubz++uv07dvXZ8rFadOm8ec//5lp06ZxySWX8OWXX3qfRLSlyMhI5syZw9NPP821115LamoqWVlZzJ8/n2HDhvm8Sz1q1Cj+/Oc/ExwczIUXXgjUjv0ZHx9PVlbWWc/QIzqQtuqOK5rHDz/8oNx///1K3759FZPJpJjNZuWCCy5Q7rvvPmXnzp2qde+66y7FarX6LWffvn3KNddcowQGBioRERHKvffeq3z33Xc+QwB4yjh06JAyduxYxWKxKF26dFHmzp2r6orvGT7gL3/5i8++OKN7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9evHSy+9xJVXXum9246OjkarbZdvYtSrvc0Vez602B0u1XD74u247eWqFruKrP9RvO4foNVhirsYxeX4uWesm7AbHsUSd1GdLXYAy2aMZtSArtJiJy12gLTYNad2mdgNHTqUoUOH8s9//rPF9yXa1rkkdpWVlQwcOJBBgwb5tMwpisL48ePZt28f+/btw2KxNHfVue6669izZw/ff/89ZrPZuzw7O5s+ffpw55138sYbb6DRaHxazEJCQvj73//OlClTfFoUr7zySjZu3MiUKVMoLi7m4osv5rXXXqO6uprbbruNV155BUVR2L17N7/61a+48847ufnmmwkJCcFisTBmzBiuvfZafve73zF8+HDVF03Xrl35+OOPCQoKon///h1uEOf2ltidD4Y88znFVQ6f5SdeuR13ZQkxv1lAQFg3AKpzDpO9KB1dYBjdH3yn3nJDzAZ2PiVT/QnR3NrlLbtMJyYaw9Nh4uWXX/ZJUDQaDa+88kqLdaQoLCxk7dq1zJgxQ5XUQe0d6+23387/+3//z+fu0J+tW7cC8MUXX3Dq1CnVY57169ezf/9+Nm7cyLJly1i5ciVPP/00BoOBiy66CL1e79NK56HRaFi9ejUAf/3rX9mxYwefffYZYWFhlJWV+dyJC3GmL/Zl+03qANyVJeiCIrxJHYCxS2+0lmBc5YU4ywv9budRXOVg/X7flkchxLlpd4mdDE58flMUxft4sb6fXbt2eTtM1NVBom/fvt6OFLt27WqwzMYkYR4HDx5EURQGDBjgNz5gwACKior8Poo7k+cxQXh4ONHR0arHtwEBAbz99tsMGjSI8ePH88wzz/DKK68AtY9pznw0czqNRuN9ZBUcHExUVBTh4eHodLVzc1ZVVTXuw4rz1kvrvq837m+eWI2u9kaj6odtPrEzvfh5VoPrCCGapt11nvAMTiyJ3fmpsrKyUb2htVotXbt29XaYqMucOXNYtGgRF198cb1JEEB5eTlWq7VJ9W1KMng2LrroItVj5KSkJMrLyzlx4oT3nZ6m8hwHvf7c/vkritLhHuWKpjmYW153UGfAWZqP21mDVh8AgLumEtfPLXWOgpN1b9uY8oUQZ6XdJXaeMezkUayoj9vtJj09vcF35ywWC+np6Tz22GPNuv++ffui0WjYv38/N910k098//79hIaGEhkZiUaj8UkAz3xpvqk8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HXXe1ZEjR/L111/LKxWdxMHc8oZXasflC3E+aleJnbxj59+2bdt48MEHGTRoEFarlR49ejDxppv4/qmnYMQI6N4dd0wMi2NjSR0wgNhu3bBarQwePJhnn33WpweRaHk5OTnnNANDbm5uh/y3MHLkSLKzszl+/HhbV0Wco5xSu2qe2JbgdCvklsr1SYjm1K7GsRP+Pf/883z11VdMmDCBhEGDyF66lNcyMkjMyGALMBioBO4GRgL3aTREDR9OZr9+zJ07l/Xr1/Of//xHxglsRWd2828qt9uN2+1Gp9M1U41ax4gRI4Da9wt79uzZxrUR5+LrIwUNr9QMthwpIPWiujtZCCGapl212An/Zs6cybFjx3jlL39h2sqVPPHVV2wCnMCff14nAPgKyAT+T1G495tvePvbb5k7axYbN270GWRStKyAgIBz2l6r1Xa4pA5qx5rq1auXvGfXCVTVuBpeqQPtR4jzhSR2HcCll15amyhMmwZffAGKQj9gELD/53UCgEtP38jlgqwsbvp59Pr9+/cjWk/Xrl2b3BvW4/TBQzsiz3t2omMzB7TOjUVr7UeI80W7ehQr79jV49tv4bTpZhQgh9rkrk4uF9m7dwN4R0UXraNfv37s3LmTkpIS78jt33//vXc2gREjRmAymSguLvbO1PDTTz8BtbNRDBw4kHfffZc77rijbT7AORg5ciQrV66kuroao9HY1tURZ2lkr9YZPLi19iPE+aJdJXaiHvPng14PP0/98h7wI/BMA5u9ANh0Oq677roWrqA4nVarZcuWLaqpcfbv3+9tOU1ISMBkMlFUVMSGDRtU227YsIENGzawZ8+eDpnYjRgxgurqar777juGDx/e1tURZynKZkKv1ag6UOT+6znc9nJcFbXTNtkPbyd72f8BEDHuYfTBkdhP7qN403sA/5+9846Potoe+He2ZFuy6Q2IJFJC0QCRFnwogoCCRg0CDwVF4YnCE54gIgoKNuz+xIqCwBMFQRFBQAQeoECoIiVUKaGml80m2WTb749lF4bZhAjpmS+ffCBz7tw5c/cye+bcc8/BlufKU+duow6MJPiuf3v6UykEwozaarkfGZmGgmzY1QXMZpe37qJRdxgYAyQAj5Zz2hvAOuBTu52A8+chIKCqNZW5jFOnTjF79mxycnLKXJaNiYnxFIV3k5SUxM0331wNGlYN7du3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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from benchq.compilation.graph_states import jl\n", + "from benchq.visualization_tools.plot_graph_state import plot_graph_state\n", + "\n", + "asg, _, __ = jl.get_rbs_graph_state_data(clifford_t_circuit, takes_graph_input=False, gives_graph_output=False, verbose=False)\n", + "asg = jl.python_asg(asg)\n", + "\n", + "plot_graph_state(asg, pauli_tracker)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "Here we see a simple chain graph because our circuit structure simpy passes the qubits down the line generated by decomposing to clifford + T.\n", + "\n", + "THere are two types of measurements which are required to perform the computation.\n", + "1. T basis measurements, the order of which is shown on the left.\n", + "2. Graph State preparation measurements, you can think of these as corresponding to creating all the edges for the graph on the left.\n", + "\n", + "In the next section, we will explore how \"schedules\" the 2nd type or measurements." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Summary\n", + "\n", + "Circuit graphs are generated from the icm form of a circuit.\n", + "\n", + "They are a representation of the graph state that is generated by the circuit." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting Resource Estimates from Compiled Circuits\n", + "\n", + "Rather than keep the whole graph, we extract the information we need to get resource estimates.\n", + "\n", + "We store this in a `CompiledAlgorithmImplementation` object.\n", + "\n", + "Let's make a `CompiledAlgorithmImplementation` object from our rotation circuit before it was decomposed." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GSCInfo(num_logical_qubits=4, num_layers=3, graph_creation_tocks_per_layer=Julia:\n", + "3-element Vector{Int64}:\n", + " 3\n", + " 0\n", + " 0, t_states_per_layer=Julia:\n", + "3-element Vector{Int64}:\n", + " 0\n", + " 0\n", + " 0, rotations_per_layer=Julia:\n", + "3-element Vector{Int64}:\n", + " 1\n", + " 0\n", + " 0)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "get_program_compilation_wf-1 is SUCCEEDED\n" + ] + } + ], + "source": [ + "compiled_implementation = implementation_compiler(implementation, optimization)\n", + "print(compiled_implementation.program.subroutines[0])" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you can see, the compiled circuit data involves some data that comes from how the graph was made including `t_states_per_layer` and `rotations_per_layer`. These parameters tell us how many non-clifford resources the circuit consumes at one time.\n", + "\n", + "`graph_creation_tocks_per_layer` is the number of measurement steps required to prepare that graph_state at each layer of the computation. It is used to calculate the time required to prepare the graph state.\n", + "\n", + "Next, let's use `CompiledAlgorithmImplementation` to get some resource estimates." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "distance: 14\n", + "physical qubit count: 402976.0\n", + "total time: 0.0018468\n" + ] + } + ], + "source": [ + "resource_estimate = estimator.estimate_resources_from_compiled_implementation(\n", + " compiled_implementation,\n", + " architecture_model,\n", + " ) \n", + "\n", + "\n", + "print(f\"distance: {resource_estimate.code_distance}\")\n", + "print(f\"physical qubit count: {resource_estimate.n_physical_qubits}\")\n", + "print(f\"total time: {resource_estimate.total_time_in_seconds}\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And there you go! We have some resource estimates.\n", + "\n", + "Don't worry if the estimates are a little high, that's just because we didn't choose a smaller magic state factory for this calculation." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### How to make Circuit Graph State?\n", + "\n", + "Since graph state is a stabilizer state, we measure stabilizers to generate it!\n", + "\n", + "We could measure all the stabilizers to get the graph.\n", + "\n", + "Measurements are expensive!! So how optimize?\n", + "\n", + "### Substrate Scheduler\n", + "\n", + "Tells us how to measure and which can be measured simultaneously." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[2, 5, 8, 11, 14, 17, 20], [0, 3, 6, 9, 12, 15, 18, 21], [1, 4, 7, 10, 13, 16, 19, 22]]\n" + ] + } + ], + "source": [ + "from benchq.compilation.graph_states.substrate_scheduler.python_substrate_scheduler import python_substrate_scheduler\n", + "\n", + "schedule = python_substrate_scheduler(asg, \"fast\")\n", + "\n", + "formatted_measurement_steps = [\n", + " [node[0] for node in step] for step in schedule.measurement_steps\n", + "]\n", + "print(formatted_measurement_steps)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from benchq.visualization_tools.plot_substrate_scheduling import plot_graph_state_with_measurement_steps\n", + "\n", + "plot_graph_state_with_measurement_steps(\n", + " asg, schedule.measurement_steps\n", + ")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Problem! Graph can get too big to handle!\n", + "\n", + "#### Solution! Use subcircuits.\n", + "\n", + "Quantum Algorithms are made up of repeated components.\n", + "\n", + "Estimate resources for each component & multiply by the number of times it was used.\n", + "\n", + "Will create a higher estimate.\n", + "\n", + "More on this later!" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## FINALLY! Pretty Graph Time!\n", + "\n", + "Let's look at the graphs of circuits to examine measurement steps!" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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W7duVXh4uHJycrR8+XI99dRTpiMBAIBSwMob5SI+Pl4tW7ZUlSpVlJycTJkEAMCHUChRpoqKivTee+8pMjJSzz//vNasWcOxcgAAfAwrb5SZ7Oxsde3aVbNnz9b777+vP/zhDxwrBwDAB1EoUSb27Nmj8PBwZWRk6KuvvlJERITpSAAAoIxQKFHqEhMT9dJLL6lSpUpat26d7rnnHtORAABAGeI9lChVY8aM0XPPPad7771XycnJlEkAAGyAQolSkZ+fr969eysmJka9evXSN998o+rVq5uOBQAAygErb7jt6NGjevnll5WUlKRx48YpKirKdCQAAFCOKJRwy9atWxUWFqbc3FwtX75cTz75pOlIAACgnLHyRoldOFZerVo1JScnUyYBALApCiVuWFFRkf785z8rMjJSL7zwgtasWaPbbrvNdCwAAGAIK2/ckOzsbL3xxhuKj4/XX//6V73zzjscKwcAwOYolLhuFx8rT0hIUFhYmOlIAADAA1AocV0uHCuvXLmy1q9fr7vvvtt0JAAA4CF4DyWuafTo0Xruued03333aePGjZRJAABwCQolriovL08xMTHq3bu3evfuzbFyAADgEitvuHT06FG99NJLWrdunT799FN1797ddCQAAOChKJS4wvfff6/w8HDl5uZqxYoVeuKJJ0xHAgAAHoyVNy4xe/bsS46VUyYBAMC1UCgh6T/Hyl966SW1a9eOY+UAAOC6sfKGsrOz9frrr2vOnDkcKwcAADeMQmlzu3fvVnh4uHbv3q2EhAS1a9fOdCQAAOBlWHnb2MqVK/Xwww/r7NmzWr9+PWUSAACUCIXSpkaPHq02bdro/vvv51g5AABwC4XSZvLy8tSrV6/iY+WLFi1StWrVTMcCAABejPdQ2sjRo0cVGRmp9evX67PPPlO3bt1MRwIAAD6AQmkTHCsHAABlhZW3DcyaNUstW7ZU9erVtWnTJsokAAAoVRRKH1ZUVKQ//elPevnllxUWFqbVq1erfv36pmMBAAAfw8rbR118rPx//ud/9Pbbb3OsHAAAlAkKpQ+6cKx8z549HCsHAABljpW3j1mxYgXHygEAQLmiUPoIy7I0atQotWnTRg888IA2btyou+66y3QsAABgAxRKH3DhWHmfPn3Ut29fLVy4kGPlAACg3PAeSi935MgRvfTSSxwrBwAAxlAovdh3332n8PBwnT9/XitXrlTLli1NRwIAADbEyttLzZw5U0888YRq1qyp5ORkyiQAADCGQullioqK9Mc//lEdO3ZUWFiYVq1axbFyAABgFCtvL3LmzBm99tprmjt3rv72t7/prbfe4lg5AAAwjkLpJTIyMhQWFqbMzEzNnTtXL774oulIAAAAklh5e4Xly5fr4Ycf1vnz57V+/XrKJAAA8CgUSg9mWZZGjBih3/zmN2rRooU2bNjAsXIAAOBxKJQeKi8vT9HR0erXr5/69evHsXIAAOCxeA+lBzpy5IgiIyO1ceNGjR8/Xm+++abpSAAAAFdFofQw3377rcLDw5WXl6eVK1fq8ccfNx0JAADgF7Hy9iAzZszQE088oVq1amnTpk2USQAA4BUolB6gqKhIQ4cOVadOnRQREaHVq1erXr16pmMBAABcF1behl18rPx///d/5XQ6OVYOAAC8CoXSoF27dik8PFz79u3TvHnz9MILL5iOBAAAcMNYeRuybNkyPfLII8XHyimTAADAW1Eoy5llWfr444/Vtm1bPfTQQ9q4caPuvPNO07EAAABKjEJZji4cK+/fv78GDBigBQsWqGrVqqZjAQAAuIX3UJaTw4cPKzIyUsnJyZo4caLeeOMN05EAAABKBYWyHGzZskURERHKz89XYmKiHnvsMdORAAAASg0r7zL25Zdf6sknn1Tt2rW1adMmyiQAAPA5FMoycuFYeefOndWhQwetWrVKt956q+lYAAAApY6Vdxk4ffq0XnvtNc2bN09///vfFRcXx7FyAADgsyiUpWzXrl0KCwvT/v37NX/+fD3//POmIwEAAJQpVt6laNmyZXr44YeVn5+vDRs2UCYBAIAtUChLgWVZ+te//qW2bdvqkUce0YYNG3THHXeYjgUAAFAuKJRuOn/+vKKiojRgwAANHDhQ8+fP51g5AACwFd5D6YbDhw+rQ4cO2rRpkyZNmqTXX3/ddCQAAIByR6EsoS1btig8PFwFBQUcKwcAALbGyrsELhwrr1OnDsfKAQCA7VEob0BRUZH+8Ic/qHPnzoqMjFRiYiLHygEAgO2x8r5Op0+f1quvvqr58+frgw8+UGxsLMfKAQAARKG8Lunp6QoPD+dYOQAAgAusvK9h6dKleuSRR1RQUMCxcgAAABcolFdx4Vj5b3/7W46VAwAA/AIKpQvnz59Xjx49io+VL1iwQFWqVDEdCwAAwCPxHsrLHDp0SJGRkdq8eTPHygEAAK6DrQtlkWXp6+xs7crPV/2AANVLS1NkRIQKCwuVmJioRx991HREAAAAj2fbQmlZlt46ckRf5+QoQFKBZenstm26pW5dJXz1lerWrWs6IgAAgFdwWJZlmQ5hwrfnzunVgwev+PqHVavqN1WrGkgEAADgnWz7UM7RggKXXz/p71/OSQAAALybbQvlHcHBurw6OiTdExxsIg4AAIDXsm2hvC0wUH+pWbP4TaR+kt6pXl13USgBAABuiG3fQ3nBicJC7cvPV92AANUIsO0zSgAAACVm+0IJAAAA99h25Q0AAIDSQaEEAACAWyiUAAAAcAuFEgAAAG6hUAIAAMAtFEoAAAC4hUIJAAAAt1AoAQAA4BYKJQAAANxCoQQAAIBbKJQAAABwC4USAAAAbqFQAgAAwC0USgAAALiFQgkAAAC3UCgBAADgFgolAAAA3EKhBAAAgFsolAAAAHALhRIAAABuoVACAADALRRKAAAAuIVCCQAAALdQKAEAAOAWCiUAAADcQqEEAACAWyiUAAAAcAuFEgAAAG6hUAIAAMAtFEoAAAC4hUIJAAAAt1AoAQAA4BYKJQAAANxCoQQAAIBbKJQAAABwC4USAAAAbqFQAgAAwC0USgAAALiFQgkAAAC3UCgBAADgFgolAAAA3EKhBAAAgFsolAAAAHALhRIAAABuoVACAADALRRKAAAAuIVCCQAAALf8P60/fYRyKNueAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from benchq.conversions import import_circuit\n", + "\n", + "ghz_circuit = import_circuit(QuantumCircuit.from_qasm_file(\"data/ghz_circuit.qasm\"))\n", + "\n", + "asg, _, __ = jl.get_rbs_graph_state_data(ghz_circuit, takes_graph_input=False, gives_graph_output=False, verbose=False)\n", + "asg = jl.python_asg(asg)\n", + "\n", + "schedule = python_substrate_scheduler(asg, \"fast\")\n", + "\n", + "plot_graph_state_with_measurement_steps(\n", + " asg, schedule.measurement_steps\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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t6lQiohYTP369TEMQzu9RcRrVChFRCwmODiY+vXra4VSRLxGhVJExII0flFEvEmFUkTEaor+h1Et6/No0d/g9DGz04hIADCcTqfT7BAiIuIm576DWSlU/HgeJxBsM2BwJvx3V7OTiYiFaYVSRMRK9qyCiz8SZECwATidsHHOpf+KiHiICqWIiJUU/Q84rhm5ePFHqCg3J4+IBAQVShERK4n4LzCumNlss8E9D0BwiHmZRMTyVChFRKzkyWegTaf/fF3HDkNmmpdHRAKCNuWIiFiN0wnffwWlxXD3/RASZnYiEbE4FUoRERERcYk+8hYRERERl6hQioiIiIhLVChFRERExCUqlCIiIiLiEhVKEREREXGJCqWIiIiIuESFUkRERERcokIpIiIiIi5RoRQRERERl6hQioiIiIhLVChFRERExCUqlCIiIiLiEhVKEREREXGJCqWIiIiIuESFUkRERERcokIpIiIiIi5RoRQRERERl6hQioiIiIhLVChFRERExCUqlCIiIiLiEhVKEREREXGJCqWIiIiIuESFUkRERERcokIpIiIiIi5RoRQRERERl6hQioiIiIhLVChFRERExCUqlCIiIiLiEhVKEREREXGJCqWIiIiIuESFUkRERERcokIpIiIiIi5RoRQRERERl6hQioiIiIhLVChFRERExCUqlCIiIiLiEhVKEREREXGJCqWIiIiIuESFUkRERERcokIpIiIiIi5RoRQRERERl6hQioiIiIhLVChFRERExCUqlCIiIiLiEhVKEREREXGJCqWIiIiIuESFUkRERERc8v8BHByhY++1D0kAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "h_chain_circuit = import_circuit(QuantumCircuit.from_qasm_file(\"data/h_chain_circuit.qasm\"))\n", + "\n", + "asg, _, __ = jl.get_rbs_graph_state_data(h_chain_circuit, takes_graph_input=False, gives_graph_output=False, verbose=False)\n", + "asg = jl.python_asg(asg)\n", + "\n", + "schedule = python_substrate_scheduler(asg, \"fast\")\n", + "\n", + "plot_graph_state_with_measurement_steps(\n", + " asg, schedule.measurement_steps\n", + ")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Closing Statements\n", + "\n", + "### What did we learn?\n", + "\n", + "\n", + "#### Inputs\n", + "- Circuit\n", + "- Architecture model\n", + "#### Outputs\n", + "- Number of physical qubits\n", + "- Computation time\n", + "- Number of measurement steps\n", + "\n", + "\n", + "\n", + "#### Components:\n", + "- Transpilation (pyliqtr)\n", + " - Bring to Clifford + T\n", + "- Jabalizer/ICM\n", + " - Easy way to represent circuit\n", + "- Min code distance finding\n", + " - Number of physical qubits\n", + " - Computation time\n", + "- Substrate scheduling\n", + " - number of measurement steps" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What's Next?\n", + "\n", + "- How to get resource estimate for large algorithms? (QuantumPrograms)\n", + "- Compare to other resource estimators.\n", + "- Try this notebook out for yourself!!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file + "vscode": { + "interpreter": { + "hash": "fbda94f5ddcb73da906661b05314820b4a1597f16c608ce3a58aaa500dc8b85a" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/pyproject.toml b/pyproject.toml index 2a27564b..d7ffa56f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,6 +45,9 @@ module = [ 'numba.*', 'juliapkg.*', 'urllib3.*', + 'pandas.*', + 'upsetplot.*', + 'pkg_resources.*', ] ignore_missing_imports = true diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..be81f79b --- /dev/null +++ b/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +markers = + slow: Tests that take long time to run locally. Skipped by 'make test-fast'. +# By default, treat warnings as errors +filterwarnings = + error + ignore:module 'sre_constants' is deprecated:DeprecationWarning \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index c64823da..3bcdea31 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,6 +47,7 @@ install_requires = cvxpy==1.3.2 aiohttp~=3.9.0 setuptools<=65.6.3 + UpSetPlot==0.9.0 [options.packages.find] where = src @@ -59,6 +60,7 @@ dev = numba~=0.57.0 benchq[pyscf] benchq[azure] + benchq[jabalizer] pyright pyscf = @@ -72,3 +74,7 @@ azure = pyqir==0.8.0 qiskit_qir==0.3.1 qiskit_ionq==0.3.10 + +jabalizer = + pauli_tracker + mbqc_scheduling diff --git a/src/benchq/algorithms/data_structures/__init__.py b/src/benchq/algorithms/data_structures/__init__.py index d92d82cf..1d6eaaa1 100644 --- a/src/benchq/algorithms/data_structures/__init__.py +++ b/src/benchq/algorithms/data_structures/__init__.py @@ -6,4 +6,3 @@ # Data structures used to represent algorithms and how they are implemented from .error_budget import ErrorBudget -from .graph_partition import GraphPartition diff --git a/src/benchq/algorithms/data_structures/algorithm_implementation.py b/src/benchq/algorithms/data_structures/algorithm_implementation.py index d0862e49..a5d9c701 100644 --- a/src/benchq/algorithms/data_structures/algorithm_implementation.py +++ b/src/benchq/algorithms/data_structures/algorithm_implementation.py @@ -1,17 +1,13 @@ from dataclasses import dataclass -from typing import Generic, TypeVar from ...conversions import SUPPORTED_CIRCUITS, import_circuit -from ...problem_embeddings import QuantumProgram, get_program_from_circuit +from ...problem_embeddings import QuantumProgram from .error_budget import ErrorBudget -from .graph_partition import GraphPartition - -T = TypeVar("T", QuantumProgram, GraphPartition) @dataclass -class AlgorithmImplementation(Generic[T]): - program: T +class AlgorithmImplementation: + program: QuantumProgram error_budget: ErrorBudget n_shots: int @@ -19,5 +15,27 @@ class AlgorithmImplementation(Generic[T]): def from_circuit( cls, circuit: SUPPORTED_CIRCUITS, error_budget: ErrorBudget, n_shots: int = 1 ): - program = get_program_from_circuit(import_circuit(circuit)) + program = QuantumProgram.from_circuit(import_circuit(circuit)) return AlgorithmImplementation(program, error_budget, n_shots) + + def transpile_to_clifford_t(self): + return AlgorithmImplementation( + self.program.transpile_to_clifford_t( + self.error_budget.transpilation_failure_tolerance + ), + self.error_budget, + self.n_shots, + ) + + @property + def n_t_gates_after_transpilation(self): + return self.program.get_n_t_gates_after_transpilation( + self.error_budget.transpilation_failure_tolerance + ) + + def compile_to_native_gates(self, verbose: bool = False): + return AlgorithmImplementation( + self.program.compile_to_native_gates(verbose), + self.error_budget, + self.n_shots, + ) diff --git a/src/benchq/algorithms/data_structures/graph_partition.py b/src/benchq/algorithms/data_structures/graph_partition.py deleted file mode 100644 index 34339e18..00000000 --- a/src/benchq/algorithms/data_structures/graph_partition.py +++ /dev/null @@ -1,32 +0,0 @@ -from dataclasses import dataclass -from typing import List, Union - -import networkx as nx -from cirq.circuits.circuit import Circuit as CirqCircuit -from orquestra.quantum.circuits import Circuit as OrquestraCircuit -from qiskit.circuit import QuantumCircuit as QiskitCircuit - -from ...problem_embeddings.quantum_program import QuantumProgram - -AnyCircuit = Union[OrquestraCircuit, CirqCircuit, QiskitCircuit] - - -@dataclass -class GraphPartition: - program: QuantumProgram - subgraphs: List[nx.Graph] - - @property - def n_nodes(self) -> int: - n_nodes = 0 - for subgraph in self.subgraphs: - n_nodes += subgraph.number_of_nodes() - return n_nodes - - @property - def n_t_gates(self) -> int: - return self.program.n_t_gates - - @property - def n_rotation_gates(self) -> int: - return self.program.n_rotation_gates diff --git a/src/benchq/algorithms/gsee/qpe_gsee.py b/src/benchq/algorithms/gsee/qpe_gsee.py index a5b13bef..0dfe1bf3 100644 --- a/src/benchq/algorithms/gsee/qpe_gsee.py +++ b/src/benchq/algorithms/gsee/qpe_gsee.py @@ -1,26 +1,22 @@ import warnings import numpy as np -from orquestra.integrations.cirq.conversions import ( - to_openfermion, # pyright: ignore[reportPrivateImportUsage] -) -from orquestra.quantum.operators import PauliRepresentation +from pyLIQTR.QSP.Hamiltonian import Hamiltonian from ...algorithms.data_structures import AlgorithmImplementation, ErrorBudget -from ...conversions import openfermion_to_pyliqtr -from ...problem_embeddings import get_qsp_program +from ...conversions import SUPPORTED_OPERATORS, get_pyliqtr_operator +from ...problem_embeddings.qsp import get_qsp_program -def _n_block_encodings(hamiltonian: PauliRepresentation, precision: float): - pyliqtr_operator = openfermion_to_pyliqtr(to_openfermion(hamiltonian)) - - return int(np.ceil(np.pi * (pyliqtr_operator.alpha) / (precision))) +def _n_block_encodings(hamiltonian: Hamiltonian, precision: float) -> int: + return int(np.ceil(np.pi * (hamiltonian.alpha) / (precision))) def qpe_gsee_algorithm( - hamiltonian: PauliRepresentation, precision: float, failure_tolerance: float -): + hamiltonian: SUPPORTED_OPERATORS, precision: float, failure_tolerance: float +) -> AlgorithmImplementation: warnings.warn("This is experimental implementation, use at your own risk.") + hamiltonian = get_pyliqtr_operator(hamiltonian) n_block_encodings = _n_block_encodings(hamiltonian, precision) program = get_qsp_program(hamiltonian, n_block_encodings) error_budget = ErrorBudget.from_even_split(failure_tolerance) diff --git a/src/benchq/algorithms/profolio_optimization.py b/src/benchq/algorithms/profolio_optimization.py index 507e987f..570e9a91 100644 --- a/src/benchq/algorithms/profolio_optimization.py +++ b/src/benchq/algorithms/profolio_optimization.py @@ -3,7 +3,7 @@ ################################################################################ from orquestra.quantum.operators import PauliSum -from ..problem_embeddings._qaoa import get_qaoa_program +from ..problem_embeddings.qaoa._qaoa import get_qaoa_program from .data_structures import AlgorithmImplementation, ErrorBudget diff --git a/src/benchq/algorithms/time_evolution.py b/src/benchq/algorithms/time_evolution.py index d7c5fd79..3f2d245b 100644 --- a/src/benchq/algorithms/time_evolution.py +++ b/src/benchq/algorithms/time_evolution.py @@ -1,19 +1,18 @@ import numpy as np -from orquestra.integrations.cirq.conversions import ( - to_openfermion, # pyright: ignore[reportPrivateImportUsage] -) from orquestra.quantum.operators import PauliRepresentation from pyLIQTR.QSP import gen_qsp +from pyLIQTR.QSP.Hamiltonian import Hamiltonian from ..algorithms.data_structures import AlgorithmImplementation, ErrorBudget -from ..conversions import openfermion_to_pyliqtr -from ..problem_embeddings import get_qsp_program, get_trotter_program +from ..conversions import SUPPORTED_OPERATORS, get_pyliqtr_operator +from ..problem_embeddings.qsp import get_qsp_program +from ..problem_embeddings.trotter import get_trotter_program # TODO: This logic is copied from pyLIQTR, perhaps we want to change it to our own? def _get_steps(tau, req_prec): # have tau and epsilon, backtrack in order to get steps - steps, closeval = gen_qsp.get_steps_from_logeps(np.log(req_prec), tau, 1) + steps, close_val = gen_qsp.get_steps_from_logeps(np.log(req_prec), tau, 1) # print(':------------------------------------------') # print(f': Steps = {steps}') while gen_qsp.getlogepsilon(tau, steps) > np.log(req_prec): @@ -21,10 +20,10 @@ def _get_steps(tau, req_prec): return steps -def _n_block_encodings_for_time_evolution(hamiltonian, time, failure_tolerance): - pyliqtr_operator = openfermion_to_pyliqtr(to_openfermion(hamiltonian)) - - tau = time * pyliqtr_operator.alpha +def _n_block_encodings_for_time_evolution( + hamiltonian: Hamiltonian, time: float, failure_tolerance: float +): + tau = time * hamiltonian.alpha steps = _get_steps(tau, failure_tolerance) # number of steps needs to be odd for QSP @@ -35,7 +34,7 @@ def _n_block_encodings_for_time_evolution(hamiltonian, time, failure_tolerance): def qsp_time_evolution_algorithm( - hamiltonian: PauliRepresentation, time: float, failure_tolerance: float + hamiltonian: SUPPORTED_OPERATORS, time: float, failure_tolerance: float ) -> AlgorithmImplementation: """Returns a program that implements time evolution using QSP. @@ -44,8 +43,9 @@ def qsp_time_evolution_algorithm( time: time of the evolution failure_tolerance: how often the algorithm can fail """ + pyliqtr_hamiltonian = get_pyliqtr_operator(hamiltonian) n_block_encodings = _n_block_encodings_for_time_evolution( - hamiltonian, time, failure_tolerance + pyliqtr_hamiltonian, time, failure_tolerance ) program = get_qsp_program(hamiltonian, n_block_encodings, decompose_select_v=False) return AlgorithmImplementation( diff --git a/src/benchq/compilation/__init__.py b/src/benchq/compilation/__init__.py index 1c0716a1..e69de29b 100644 --- a/src/benchq/compilation/__init__.py +++ b/src/benchq/compilation/__init__.py @@ -1,20 +0,0 @@ -################################################################################ -# © Copyright 2022-2023 Zapata Computing Inc. -################################################################################ -import os -import pathlib - -from .initialize_julia import jl, juliapkg -from .julia_utils import ( - get_algorithmic_graph_and_icm_output, - get_algorithmic_graph_from_Jabalizer, - get_algorithmic_graph_from_ruby_slippers, - get_ruby_slippers_compiler, -) -from .pyliqtr_transpilation import pyliqtr_transpile_to_clifford_t -from .transpile_to_native_gates import transpile_to_native_gates - -jl.include( - os.path.join(pathlib.Path(__file__).parent.resolve(), "jabalizer_wrapper.jl"), -) -jl.include(os.path.join(pathlib.Path(__file__).parent.resolve(), "ruby_slippers.jl")) diff --git a/src/benchq/compilation/circuits/__init__.py b/src/benchq/compilation/circuits/__init__.py new file mode 100644 index 00000000..99928ca7 --- /dev/null +++ b/src/benchq/compilation/circuits/__init__.py @@ -0,0 +1,5 @@ +from .compile_to_native_gates import compile_to_native_gates +from .pyliqtr_transpilation import ( + get_num_t_gates_per_rotation, + pyliqtr_transpile_to_clifford_t, +) diff --git a/src/benchq/compilation/transpile_to_native_gates.py b/src/benchq/compilation/circuits/compile_to_native_gates.py similarity index 84% rename from src/benchq/compilation/transpile_to_native_gates.py rename to src/benchq/compilation/circuits/compile_to_native_gates.py index 39057e2d..59c685b8 100644 --- a/src/benchq/compilation/transpile_to_native_gates.py +++ b/src/benchq/compilation/circuits/compile_to_native_gates.py @@ -1,3 +1,4 @@ +import time from typing import Iterable, Sequence import numpy as np @@ -21,21 +22,30 @@ decompose_operation, ) -from ..conversions._circuit_translations import import_circuit +from ...conversions._circuit_translations import import_circuit -def transpile_to_native_gates(circuit) -> Circuit: - """Traspile common gates to clifford + RZ gates. +def compile_to_native_gates(circuit, verbose=False) -> Circuit: + """Transpile common gates to clifford + RZ gates. Changes RX, RY, and U3 to RZ. Changes CCX to T gates. Also, translates rotations with some characteristic angles (-pi, -pi/2, -pi/4, 0, pi/4, pi/2, pi) to simpler gates. """ + if verbose: + print("Compiling to native gates...") circuit = import_circuit(circuit) # Hack: decompose drops n_qubits from the original circuits, so we add it back return Circuit( decompose_benchq_circuit( circuit, - [CCZtoT(), CCXtoT(), U3toRZ(), RXtoRZ(), RYtoRZ(), DecomposeStandardRZ()], + [ + CCZtoT(), + CCXtoT(), + U3toRZ(), + RXtoRZ(), + RYtoRZ(), + DecomposeStandardRZ(), + ], ).operations, n_qubits=circuit.n_qubits, ) @@ -47,12 +57,44 @@ def decompose_benchq_circuit( return Circuit(decompose_benchq_operations(circuit.operations, decomposition_rules)) +class ProgressIterator: + def __init__(self, iterable): + self.iterable = iterable + self.iterator = iter(iterable) + self.length = len( + iterable + ) # Assumes the iterable has a length (e.g., list, tuple) + self.index = 0 + + def __iter__(self): + return self + + def __next__(self): + if self.index == 0: + self.start_time_time = time.time() + if self.index >= self.length: + print("\rProgress: 100.00% ") + raise StopIteration + self.index += 1 + self.show_progress() + return next(self.iterator) + + def show_progress(self): + if self.index % 10000 == 0: + progress = (self.index / self.length) * 100 + elapsed_time = time.time() - self.start_time_time + print( + f"\r{progress:.2f}% ({self.index}) completed in {elapsed_time:.2f}s", + end="", + ) + + def decompose_benchq_operations( operations: Iterable[Operation], decomposition_rules: Sequence[DecompositionRule[GateOperation]], ): decomposed_operation_sequence = [] - for op in operations: + for op in ProgressIterator(operations): if isinstance(op, GateOperation): for decomposed_op in decompose_operation(op, decomposition_rules): decomposed_operation_sequence += [decomposed_op] @@ -95,13 +137,13 @@ def production(self, operation: GateOperation) -> Iterable[GateOperation]: elif np.isclose(theta, np.pi) or np.isclose(theta, -np.pi): return [Z(*operation.qubit_indices)] elif np.isclose(theta, -np.pi / 4): - return [Dagger(T)(*operation.qubit_indices)] + return [T.dagger(*operation.qubit_indices)] elif np.isclose(theta, -np.pi / 2): - return [Dagger(S)(*operation.qubit_indices)] + return [S.dagger(*operation.qubit_indices)] elif np.isclose(theta, -3 * np.pi / 4): return [ - Dagger(S)(*operation.qubit_indices), - Dagger(T)(*operation.qubit_indices), + S.dagger(*operation.qubit_indices), + T.dagger(*operation.qubit_indices), ] else: raise RuntimeError( diff --git a/src/benchq/compilation/pyliqtr_transpilation.py b/src/benchq/compilation/circuits/pyliqtr_transpilation.py similarity index 86% rename from src/benchq/compilation/pyliqtr_transpilation.py rename to src/benchq/compilation/circuits/pyliqtr_transpilation.py index a94c3d1a..3080cc04 100644 --- a/src/benchq/compilation/pyliqtr_transpilation.py +++ b/src/benchq/compilation/circuits/pyliqtr_transpilation.py @@ -2,15 +2,17 @@ # © Copyright 2022 Zapata Computing Inc. ################################################################################ import warnings +from decimal import Decimal, getcontext +from math import ceil from typing import Optional, Union -from cirq.circuits import Circuit as CirqCircuit +from cirq.circuits.circuit import Circuit as CirqCircuit from orquestra.quantum.circuits import Circuit as OrquestraCircuit from orquestra.quantum.circuits import GateOperation from pyLIQTR.gate_decomp.cirq_transforms import clifford_plus_t_direct_transform from qiskit.circuit import QuantumCircuit as QiskitCircuit -from ..conversions import export_circuit, import_circuit +from ...conversions import export_circuit, import_circuit def pyliqtr_transpile_to_clifford_t( @@ -70,3 +72,18 @@ def pyliqtr_transpile_to_clifford_t( ) return import_circuit(compiled_cirq_circuit, orquestra_circuit.n_qubits) + + +# Assumes gridsynth scaling +SYNTHESIS_SCALING = 4 +getcontext().prec = 100 + + +def get_num_t_gates_per_rotation( + per_gate_synthesis_accuracy: Union[float, Decimal] +) -> int: + return ceil( + SYNTHESIS_SCALING + * (1 / Decimal(per_gate_synthesis_accuracy)).log10() + / Decimal(2).log10() + ) diff --git a/src/benchq/compilation/graph_sim_data.jl b/src/benchq/compilation/graph_sim_data.jl deleted file mode 100644 index 7f8380be..00000000 --- a/src/benchq/compilation/graph_sim_data.jl +++ /dev/null @@ -1,152 +0,0 @@ -################################################################################ -# © Copyright 2022-2023 Zapata Computing Inc. -################################################################################ -#= -This contains the data required to run the graph simulation algorithm. -These tables are used to speed up the graph simulation algorithm by memoizing -the results of certain small calculations which are performed repeatedly. -=# - -# numbers which correspond to each of the gates in multiply_UInt8 -const Pauli_code = UInt8(1) -const S_code = UInt8(2) -const S_Dagger_code = UInt8(2) # S and S_Dagger are equal up to a pauli -const H_code = UInt8(3) -const SQRT_X_code = UInt8(4) -const SH_code = UInt8(5) -const HS_code = UInt8(6) - -# Two qubit gates -const CZ_code = UInt8(7) -const CNOT_code = UInt8(8) - -# Gates that get decomposed -const T_code = UInt8(9) -const T_Dagger_code = UInt8(10) -const RX_code = UInt8(11) -const RY_code = UInt8(12) -const RZ_code = UInt8(13) - -const MEASURE_OFFSET = (RZ_code - T_code + 0x1) - -# Measurement markers -const M_T_code = MEASURE_OFFSET + T_code -const M_T_Dagger_code = MEASURE_OFFSET + T_Dagger_code -const M_RX_code = MEASURE_OFFSET + RX_code -const M_RY_code = MEASURE_OFFSET + RY_code -const M_RZ_code = MEASURE_OFFSET + RZ_code - -# enumerate the supported gates -const op_list = [ - "I", - "X", - "Y", - "Z", - "H", - "S", - "S_Dagger", - "CZ", - "CNOT", - "T", - "T_Dagger", - "RX", - "RY", - "RZ", - "SX", - "SX_Dagger", - "RESET", -] - -# convert indices of supported gates to the corresponding code -const code_list = UInt8[ - 0, - 0, - 0, - 0, - H_code, - S_code, - S_Dagger_code, - CZ_code, - CNOT_code, - T_code, - T_Dagger_code, - RX_code, - RY_code, - RZ_code, - SQRT_X_code, - SQRT_X_code, - 0, -] - - - -#= -""" -Lookup table for the product of two local clifford operations. -The index of the table corresponds to the first local clifford operation and the -value of the table corresponds to the second local clifford operation. The value -of the table is the local clifford operation that is the product of the two -local clifford operations. -""" -const multiply_UInt8 = UInt8[ - 1 2 3 4 5 6 - 2 1 6 5 4 3 - 3 5 1 6 2 4 - 4 6 5 1 3 2 - 5 3 4 2 6 1 - 6 4 2 3 1 5 -] - -const _multiply_h = multiply_UInt8[H_code, :] -const _multiply_s = multiply_UInt8[S_code, :] -const _multiply_d = multiply_UInt8[S_Dagger_code, :] - -const _multiply_by_s = multiply_UInt8[:, S_code] -const _multiply_by_sqrt_x = multiply_UInt8[:, SQRT_X_code] -=# - -#= -Product of two local clifford operations: - multiply_h & multiply_s store the results of multiplying h or s by the given value - multiply_by_* store the results of multiplying the value by s (sqrt_z) or sqrt_x - This is done by packing the row or column from the multiply_UInt8 table into a 32-bit - unsigned integer, where each nibble is one of the values (all shifted up by 4 to avoid - a shift at runtime. -=# -_unpack(c, v) = (c >> (v << 2)) & 0x7 - -multiply_h(v) = _unpack(0x4261530, v) -multiply_s(v) = _unpack(0x3456120, v) -multiply_by_s(v) = _unpack(0x4365120, v) -multiply_by_sqrt_x(v) = _unpack(0x3216540, v) - -# Packing functions to more efficiently store CZ data -c0(a, b) = UInt8((a << 4) | b) -c1(a, b) = c0(a, b) | 0x80 - -""" -Lookup table for the product of a CZ gate and a local clifford operation. - -The first and second indices of the table correspond to the local clifford operation on the -first and second nodes respectively. -The first value of the table is 0 if the the nodes are not connected -after applying the CZ gate and 1 if they are connected after applying the CZ gate. -The second and third values of the table are the local clifford operations on the -first and second nodes respectively after applying the CZ gate. -""" -const cz_isolated = [ - c1(1, 1) c1(1, 2) c0(1, 3) c1(1, 1) c1(1, 2) c0(1, 3) - c1(2, 1) c1(2, 2) c0(2, 3) c1(2, 1) c1(2, 2) c0(2, 3) - c0(3, 1) c0(3, 2) c0(3, 3) c0(3, 1) c0(3, 2) c0(3, 3) - c1(1, 1) c1(1, 2) c0(1, 3) c1(1, 1) c1(1, 2) c0(1, 3) - c1(2, 1) c1(2, 2) c0(2, 3) c1(2, 1) c1(2, 2) c0(2, 3) - c0(3, 1) c0(3, 2) c0(3, 3) c0(3, 1) c0(3, 2) c0(3, 3) -] -const cz_connected = [ - c0(1, 1) c0(1, 2) c1(2, 6) c0(2, 1) c0(2, 2) c1(2, 3) - c0(2, 1) c0(2, 2) c1(1, 6) c0(1, 1) c0(1, 2) c1(1, 3) - c1(6, 2) c1(6, 1) c0(1, 1) c0(2, 2) c0(2, 1) c0(1, 2) - c0(1, 2) c0(1, 1) c0(2, 2) c1(5, 5) c1(5, 4) c0(2, 1) - c0(2, 2) c0(2, 1) c0(1, 2) c1(4, 5) c1(4, 4) c0(1, 1) - c1(3, 2) c1(3, 1) c0(2, 1) c0(1, 2) c0(1, 1) c0(2, 2) -] diff --git a/src/benchq/compilation/graph_states/README.md b/src/benchq/compilation/graph_states/README.md new file mode 100644 index 00000000..9e4c9631 --- /dev/null +++ b/src/benchq/compilation/graph_states/README.md @@ -0,0 +1,22 @@ +# The Ruby Slippers Compiler + +Here we provide tools for compiling a quantum program written in Julia. This is probably the most complex section of benchq where we keep most of the unique tools that BenchQ provides. The main tool we provide is the Ruby Slippers compiler, which is a Julia compiler that can be called from Python. This compiler is designed to be used with the [Orquestra](https://www.zapatacomputing.com/orquestra/) quantum computing platform, but translating from other platforms to orquestra should be relatively straightforward. + +This code works particularly well for compiling large quantum circuits at the same time, as opposed to the [Jabalizer](https://github.com/QSI-BAQS/Jabalizer.jl) tool, which breaks the circuit up into smaller pieces. Unfortunately, because making the widgets includes a significant amount of overhead, this tool is not well suited for compiling small circuits. It also produces ASGs of lower quality than Jabalizer. The main advantage of this package is the sheer number of available compilation options. We will cover these in detail below. + +## Installation + +As noted in the main README of BenchQ, you must first install the [Julia](https://julialang.org/) programming language in order to perform compilation. Here we have implemented some simple code which automatically installs Julia if we cannot find it on your system. This is fast and simple to use, but might irk some users. If you would like to install Julia yourself, you can do so by following the instructions [here](https://julialang.org/downloads/). + +## Options + +The python interface for this package is generated allows for a number of options to be set when running a compilation. These options can be broadly split up into two catagories: Ruby Slippers hyperparameters and Pauli Tracking parameters. + + +### Table Generation + +The graph state simulator I use required generating several tables which can be found in `graph_sim_data.jl`. The code which generated these tables can be found in the `table_generation` folder. + +TODOs: +[ ] - Improve and run testing + diff --git a/src/benchq/compilation/graph_states/__init__.py b/src/benchq/compilation/graph_states/__init__.py new file mode 100644 index 00000000..c93fef38 --- /dev/null +++ b/src/benchq/compilation/graph_states/__init__.py @@ -0,0 +1,23 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +import os +import pathlib + +from pkg_resources import WorkingSet + +from .circuit_compilers import ( + default_ruby_slippers_circuit_compiler, + get_algorithmic_graph_and_icm_output, + get_jabalizer_circuit_compiler, + get_ruby_slippers_circuit_compiler, +) +from .implementation_compiler import get_implementation_compiler +from .initialize_julia import jl, juliapkg + +jabalizer_dependencies = ["pauli-tracker", "mbqc-scheduling"] +installed_packages = {pkg.key for pkg in WorkingSet()} +current_directory = pathlib.Path(__file__).parent.resolve() +if all(dep in installed_packages for dep in jabalizer_dependencies): + jl.include(os.path.join(current_directory, "jabalizer_wrapper.jl")) +jl.include(os.path.join(current_directory, "ruby_slippers/ruby_slippers.jl")) diff --git a/src/benchq/compilation/graph_states/circuit_compilers.py b/src/benchq/compilation/graph_states/circuit_compilers.py new file mode 100644 index 00000000..2fe89c5a --- /dev/null +++ b/src/benchq/compilation/graph_states/circuit_compilers.py @@ -0,0 +1,104 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +from datetime import datetime + +import networkx as nx +from orquestra.quantum.circuits import Circuit + +from .compiled_data_structures import GSCInfo +from .initialize_julia import jl + + +def get_nx_graph_from_rbs_adj_list(adj: list) -> nx.Graph: + graph = nx.empty_graph(len(adj)) + for vertex_id, neighbors in enumerate(adj): + for neighbor in neighbors: + graph.add_edge(vertex_id, neighbor) + + return graph + + +def default_ruby_slippers_circuit_compiler( + circuit: Circuit, + optimization: str, + verbose: bool, +) -> GSCInfo: + compiled_graph_data, _ = jl.run_ruby_slippers( + circuit, verbose=verbose, optimization=optimization + ) + return GSCInfo.from_dict(compiled_graph_data) + + +def get_ruby_slippers_circuit_compiler( + takes_graph_input: bool = True, + gives_graph_output: bool = True, + max_num_qubits: int = 1, + optimal_dag_density: int = 1, + use_fully_optimized_dag: bool = False, + teleportation_threshold: int = 40, + teleportation_distance: int = 4, + min_neighbor_degree: int = 6, + max_num_neighbors_to_search: int = int(1e5), + decomposition_strategy: int = 0, + max_graph_size: int = int(1e7), +): + def rbs_circuit_compiler( + circuit: Circuit, + optimization: str, + verbose: bool, + ) -> GSCInfo: + (compiled_graph_data, _,) = jl.run_ruby_slippers( + circuit, + verbose=verbose, + takes_graph_input=takes_graph_input, + gives_graph_output=gives_graph_output, + optimization=optimization, + max_num_qubits=max_num_qubits, + optimal_dag_density=optimal_dag_density, + use_fully_optimized_dag=use_fully_optimized_dag, + teleportation_threshold=teleportation_threshold, + teleportation_distance=teleportation_distance, + min_neighbor_degree=min_neighbor_degree, + max_num_neighbors_to_search=max_num_neighbors_to_search, + decomposition_strategy=decomposition_strategy, + max_graph_size=max_graph_size, + ) + + return GSCInfo.from_dict(compiled_graph_data) + + return rbs_circuit_compiler + + +def get_jabalizer_circuit_compiler( + space_optimal_timeout: int = 60, +): + def jabalizer_circuit_compiler( + circuit: Circuit, + optimization: str, + verbose: bool, + ) -> GSCInfo: + + compiled_graph_data = jl.run_jabalizer( + circuit, optimization, verbose, space_optimal_timeout + ) + + return GSCInfo.from_dict(compiled_graph_data) + + return jabalizer_circuit_compiler + + +def get_algorithmic_graph_and_icm_output(circuit): + svec, op_seq, icm_output, data_qubits_map = jl.run_jabalizer(circuit) + return create_graph_from_stabilizers(svec), op_seq, icm_output, data_qubits_map + + +def create_graph_from_stabilizers(svec) -> nx.Graph: + G = nx.Graph() + siz = len(svec) + for i in range(siz): + z = svec[i].Z + for j in range(i + 1, siz): + if z[j]: + G.add_edge(i, j) + return G diff --git a/src/benchq/compilation/graph_states/compiled_data_structures.py b/src/benchq/compilation/graph_states/compiled_data_structures.py new file mode 100644 index 00000000..14649b32 --- /dev/null +++ b/src/benchq/compilation/graph_states/compiled_data_structures.py @@ -0,0 +1,130 @@ +from dataclasses import dataclass +from decimal import Decimal +from typing import Callable, List, Sequence + +from ...problem_embeddings.quantum_program import QuantumProgram +from ..circuits import get_num_t_gates_per_rotation + + +@dataclass +class GSCInfo: + num_logical_qubits: int + num_layers: int + graph_creation_tocks_per_layer: List[int] + t_states_per_layer: List[int] + rotations_per_layer: List[int] + + @staticmethod + def from_dict(data: dict) -> "GSCInfo": + return GSCInfo( + data["num_logical_qubits"], + data["num_layers"], + data["graph_creation_tocks_per_layer"], + data["t_states_per_layer"], + data["rotations_per_layer"], + ) + + +class CompiledQuantumProgram: + """A quantum circuit represented as a sequence of subroutine invocations.""" + + def __init__( + self, + subroutines: Sequence[GSCInfo], + steps: int, + calculate_subroutine_sequence: Callable[[int], Sequence[int]], + ) -> None: + """Initializer for the QuantumProgram class. + + Args: + subroutines: The circuits which are used in the program. All subroutines + must act on the same number of qubits. + steps: The number of repetitions of the main repeated part of the circuit. + calculate_subroutine_sequence: A function which takes the number of steps + and returns a list containing the indices of the subroutines to be used. + + Raises: + ValueError: If the subroutines do not all act on the same number of qubits. + """ + self.num_logical_qubits = max( + subroutine.num_logical_qubits for subroutine in subroutines + ) + self.subroutines = subroutines + self.steps = steps + self.calculate_subroutine_sequence = calculate_subroutine_sequence + + @staticmethod + def from_program( + program: QuantumProgram, compiled_circuits: List[GSCInfo] + ) -> "CompiledQuantumProgram": + assert len(compiled_circuits) == len(program.subroutines) + return CompiledQuantumProgram( + compiled_circuits, + steps=program.steps, + calculate_subroutine_sequence=program.calculate_subroutine_sequence, + ) + + @property + def subroutine_sequence(self) -> Sequence[int]: + return self.calculate_subroutine_sequence(self.steps) + + @property + def n_rotation_gates(self) -> int: + n_rotation_gates_per_subroutine = [0] * len(self.subroutines) + for i, compiled_circuit in enumerate(self.subroutines): + n_rotation_gates_per_subroutine[i] = sum( + compiled_circuit.rotations_per_layer + ) + return sum( + n_rotation_gates_per_subroutine[subroutine] + for subroutine in self.subroutine_sequence + ) + + @property + def n_t_gates(self) -> int: + n_rotation_gates_per_subroutine = [0] * len(self.subroutines) + for i, compiled_circuit in enumerate(self.subroutines): + n_rotation_gates_per_subroutine[i] = sum( + compiled_circuit.t_states_per_layer + ) + return sum( + n_rotation_gates_per_subroutine[subroutine] + for subroutine in self.subroutine_sequence + ) + + @property + def t_depth(self) -> int: + """If the circuit is transpiled to a gate set containing T-gates, this + function returns the depth of the circuit in terms of T-gates. If not, + then it returns the depth in terms of non-clifford rotations. + + Returns: + int: number of T-gates in the circuit. + """ + return sum( + self.subroutines[subroutine].num_layers + for subroutine in self.subroutine_sequence + ) + + def get_n_t_gates_after_transpilation(self, transpilation_failure_tolerance: float): + if self.n_rotation_gates == 0: + return self.n_t_gates + + per_gate_synthesis_accuracy = 1 - ( + 1 - Decimal(transpilation_failure_tolerance) + ) ** Decimal(1 / self.n_rotation_gates) + + n_t_gates_per_rotation = get_num_t_gates_per_rotation( + per_gate_synthesis_accuracy + ) + + return self.n_t_gates + self.n_rotation_gates * n_t_gates_per_rotation + + +class CompiledAlgorithmImplementation: + def __init__( + self, program: CompiledQuantumProgram, algorithm_implementation + ) -> None: + self.program = program + self.n_shots = algorithm_implementation.n_shots + self.error_budget = algorithm_implementation.error_budget diff --git a/src/benchq/compilation/graph_states/implementation_compiler.py b/src/benchq/compilation/graph_states/implementation_compiler.py new file mode 100644 index 00000000..1e7e1869 --- /dev/null +++ b/src/benchq/compilation/graph_states/implementation_compiler.py @@ -0,0 +1,111 @@ +from typing import Callable, List + +from orquestra import sdk +from orquestra.quantum.circuits import Circuit + +from ...algorithms.data_structures import AlgorithmImplementation +from ..circuits.compile_to_native_gates import compile_to_native_gates +from .circuit_compilers import default_ruby_slippers_circuit_compiler +from .compiled_data_structures import ( + CompiledAlgorithmImplementation, + CompiledQuantumProgram, + GSCInfo, +) + + +@sdk.task( + source_import=sdk.GithubImport( + "zapatacomputing/benchq", + git_ref="ac/DTA2-270-implement-pauli-tracker", + ), + custom_image="hub.stage.nexus.orquestra.io/" + "zapatacomputing/benchq-ce:3eec2c8-sdk0.62.0", +) +def distributed_graph_creation( + circuit: Circuit, + optimization: str, + verbose: bool, + circuit_compiler, + circuit_num: int, + n_subroutines: int, +) -> GSCInfo: + if verbose: + print(f"\nCompiling subroutine {circuit_num+1} of {n_subroutines}...") + circuit = compile_to_native_gates(circuit, verbose) + if verbose: + print("Transferring Data to Julia...") + return circuit_compiler(circuit, optimization, verbose) + + +def get_implementation_compiler( + circuit_compiler=default_ruby_slippers_circuit_compiler, + max_subroutine_size: int = int(1e6), + destination: str = "single-thread", + num_cores: int = 3, + config_name: str = "darpa-ta1", + workspace_id: str = "darpa-phase-ii-gsc-resource-estimates-8a7c3b", + project_id: str = "migration", +) -> Callable[[AlgorithmImplementation, str, bool], CompiledAlgorithmImplementation]: + @sdk.workflow(resources=sdk.Resources(cpu=str(num_cores), memory="16Gi")) + def get_program_compilation_wf( + algorithm_implementation: AlgorithmImplementation, + optimization: str = "Space", + verbose: bool = False, + ) -> List[sdk.ArtifactFuture[GSCInfo]]: + compiled_subroutine_list = [] + program = algorithm_implementation.program + program = program.split_into_smaller_subroutines(max_subroutine_size) + for circuit_num, circuit in enumerate(program.subroutines): + compiled_subroutine_list.append( + distributed_graph_creation( + circuit, + optimization, + verbose, + circuit_compiler, + circuit_num, + len(algorithm_implementation.program.subroutines), + ) + ) + + return compiled_subroutine_list + + def parallelized_compiler( + algorithm_implementation: AlgorithmImplementation, + optimization: str = "Space", + verbose: bool = False, + ) -> CompiledAlgorithmImplementation: + if verbose: + print("Beginning compilation...") + program_compilation_wf = get_program_compilation_wf( + algorithm_implementation, + optimization, + verbose, + ) + if destination == "single-thread": + wf_run = program_compilation_wf.run("in_process") + elif destination == "local": + wf_run = program_compilation_wf.run("ray") + elif destination == "remote": + wf_run = program_compilation_wf.run( + config_name, + workspace_id=workspace_id, + project_id=project_id, + ) + compiled_subroutine_list = wf_run.get_results(wait=True) + # Hack to ensure that workflow always returns a list + if not isinstance(compiled_subroutine_list, tuple): + compiled_subroutine_list = [compiled_subroutine_list] + + if verbose: + print("Compilation complete.") + + compiled_program = CompiledQuantumProgram.from_program( + algorithm_implementation.program, + compiled_subroutine_list, # type: ignore + ) + + return CompiledAlgorithmImplementation( + compiled_program, algorithm_implementation + ) + + return parallelized_compiler diff --git a/src/benchq/compilation/initialize_julia.py b/src/benchq/compilation/graph_states/initialize_julia.py similarity index 88% rename from src/benchq/compilation/initialize_julia.py rename to src/benchq/compilation/graph_states/initialize_julia.py index 17db32b4..e19201dd 100644 --- a/src/benchq/compilation/initialize_julia.py +++ b/src/benchq/compilation/graph_states/initialize_julia.py @@ -13,7 +13,7 @@ "JSON": {"uuid": "682c06a0-de6a-54ab-a142-c8b1cf79cde6", "version": "0.21"}, "Jabalizer": { "uuid": "5ba14d91-d028-496b-b148-c0fbc366f709", - "version": "0.4.4", + "version": "0.5.0", }, "TimerOutputs": { "uuid": "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f", @@ -23,6 +23,14 @@ "uuid": "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91", "version": "0.34.0", }, + "Memoize": { + "uuid": "c03570c3-d221-55d1-a50c-7939bbd78826", + "version": "0.4.4", + }, + "Graphs": { + "uuid": "86223c79-3864-5bf0-83f7-82e725a168b6", + "version": "1.9.0", + }, }, } curr_deps = juliapkg.deps.load_cur_deps() diff --git a/src/benchq/compilation/graph_states/jabalizer_wrapper.jl b/src/benchq/compilation/graph_states/jabalizer_wrapper.jl new file mode 100644 index 00000000..4279fa12 --- /dev/null +++ b/src/benchq/compilation/graph_states/jabalizer_wrapper.jl @@ -0,0 +1,156 @@ +using Jabalizer +using Graphs +using PythonCall +import Graphs.SimpleGraphs + +function run_jabalizer(circuit, optimization, debug_flag=false, space_optimization_timeout=1) + + asg, pauli_tracker, num_layers = get_jabalizer_graph_state_data( + circuit, optimization, debug_flag, space_optimization_timeout + ) + + num_logical_qubits = get_num_logical_qubits(pauli_tracker.layering, asg, optimization, debug_flag) + debug_flag && println("Running substrate scheduler...") + if debug_flag && num_logical_qubits == num_layers && optimization == "Space" + error("Jabalizer and Ruby Slippers disagree on qubit counts.") + end + (graph_creation_tocks_per_layer, t_states_per_layer, rotations_per_layer) = + two_row_scheduler( + asg, + pauli_tracker, + num_logical_qubits, + optimization, + debug_flag, + ) + + python_compiled_data = Dict( + "num_logical_qubits" => num_logical_qubits, + "num_layers" => num_layers, + "graph_creation_tocks_per_layer" => pylist(graph_creation_tocks_per_layer), + "t_states_per_layer" => pylist(t_states_per_layer), + "rotations_per_layer" => pylist(rotations_per_layer), + ) + + return python_compiled_data +end + + +function get_jabalizer_graph_state_data(circuit, optimization, debug_flag=false, space_optimization_timeout=1) + if debug_flag + println("Compiling using Jabalizer...") + println("Converting to Jabalizer Circuit...") + end + + # Reading and caching the orquestra circuit + input_circuit::Vector{Jabalizer.Gate} = [] + num_circuit_qubits = pyconvert(Int, circuit.n_qubits) + measurements = Vector{Vector{Union{UInt8,Float64}}}([[H_code, 0.0] for _ in range(1, num_circuit_qubits)]) + for op in circuit.operations + # reset operation is not supported by jabalizer yet + if occursin("ResetOperation", pyconvert(String, op.__str__())) # reset operation + @warn "Circuit contains the 'reset' operation, which is not supported by Jabalizer. Skipping..." + continue + else + if Jabalizer.pyconvert(String, op.gate.name) == "S_Dagger" + new_gate = Jabalizer.Gate( + "S_DAG", + [], + [Jabalizer.pyconvert(Int, qubit) + 1 for qubit in op.qubit_indices] + ) + elseif Jabalizer.pyconvert(String, op.gate.name) == "I" + continue + elseif Jabalizer.pyconvert(String, op.gate.name) == "RZ" + new_gate = Jabalizer.Gate( + "RZ", + [Jabalizer.pyconvert(Float64, op.gate.params[0])], + [Jabalizer.pyconvert(Int, qubit) + 1 for qubit in op.qubit_indices] + ) + else + new_gate = Jabalizer.Gate( + Jabalizer.pyconvert(String, op.gate.name), + [], + [Jabalizer.pyconvert(Int, qubit) + 1 for qubit in op.qubit_indices] + ) + end + + end + push!(input_circuit, new_gate) + for qubit in op.qubit_indices + num_circuit_qubits = max(num_circuit_qubits, pyconvert(Int, qubit) + 1) + end + end + + registers = [i for i in 1:pyconvert(Int, circuit.n_qubits)] + + jabalizer_quantum_circuit = Jabalizer.QuantumCircuit( + registers, + input_circuit + ) + + if debug_flag + println("Compiling to Algorithm Specific Graph...") + end + + jabalizer_out = Jabalizer.mbqccompile( + jabalizer_quantum_circuit; + universal=true, + ptracking=true, + teleport=["T", "T_Dagger", "RZ"] + ) + + n_nodes = length(jabalizer_out["spatialgraph"]) + julia_spacial_graph = [Set{UInt32}(neighborhood .+ 1) for neighborhood in jabalizer_out["spatialgraph"]] + graph_input_nodes = jabalizer_out["statenodes"] .+ 1 + graph_output_nodes = jabalizer_out["outputnodes"] .+ 1 + + + measurements = [[] for _ in 1:n_nodes] + for gate in jabalizer_out["measurements"] + if gate[1] == "T" + measurements[gate[2]+1] = [T_code, 0.0] + elseif gate[1] == "T_Dagger" + measurements[gate[2]+1] = [T_Dagger_code, 0.0] + elseif gate[1] == "RZ" + # Jabalizer doesn't keep track of the angles of rotations yet + measurements[gate[2]+1] = [T_Dagger_code, gate[3]] + elseif gate[1] == "X" + measurements[gate[2]+1] = [H_code, 0.0] + else + error("Invalid measurement type.") + end + end + + for (i, measurment) in enumerate(measurements) + if measurment == [] + measurements[i] = [I_code, 0.0] + end + end + + layering = [layer .+ 1 for layer in jabalizer_out["steps"]] + + asg = AlgorithmSpecificGraph( + julia_spacial_graph, + [], + [], + n_nodes, + StitchingProperties( + true, + true, + graph_input_nodes, + graph_output_nodes, + [], + ), + ) + pauli_tracker = PauliTracker( + Vector{Vector{Vector{Qubit}}}([[[], []] for _ in 1:n_nodes]), + measurements, + n_nodes, + layering, + optimization, + 1, + 1, + false, + ) + + return asg, pauli_tracker, length(jabalizer_out["steps"]) +end \ No newline at end of file diff --git a/src/benchq/compilation/graph_states/pauli_tracker/dag_creation.jl b/src/benchq/compilation/graph_states/pauli_tracker/dag_creation.jl new file mode 100644 index 00000000..fa7ecd8b --- /dev/null +++ b/src/benchq/compilation/graph_states/pauli_tracker/dag_creation.jl @@ -0,0 +1,201 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +using Memoize + +""" +Given that pauli_tracker.cond_paulis is full, compute the DAG which results from the +conditional Pauli operators. This is done by separating the conditional Pauli operators +into two separate graphs, one for the X gates which act on qubits which are measured in +the T basis (called the static_DAG), and one for all other measurements (called the +pushable_DAG). The pushable DAG is so called because dependencies in the pushable DAG +can be "pushed" to the dependencies of the next node in the DAG. By setting the final_depth +variable, one can specify how many nodes to push a dependency to. This is useful for +choosing how sparse the DAG will be. Setting the final_depth to larger values will result +in a more dense DAG. Sparser DAGs will be easier to layer and take up less space in memory, +however, denser DAGs will have a less defined "arrow of time" and will be harder to layer. + +Attributes: + pauli_tracker (PauliTracker): The PauliTracker object containing the + information on the conditional Pauli operators and measurements + performed on each qubit. + nodes_to_include (Vector{Qubit}): The nodes which should be included + in the DAG. + final_depth (Int): How many nodes to push a dependency to. + verbose (bool): Whether to print out the progress of the function. +Returns: + dag (Vector{Vector{Qubit}}): The DAG which results from the conditional + Pauli operators. +""" +function get_dag(pauli_tracker, nodes_to_include, final_depth=1, verbose::Bool=false)::Vector{Vector{Qubit}} + pushable_dag::Vector{Vector{Qubit}} = [[] for _ in range(1, pauli_tracker.n_nodes)] + static_dag::Vector{Vector{Qubit}} = [[] for _ in range(1, pauli_tracker.n_nodes)] + + for node in VerboseIterator(nodes_to_include, verbose, "Creating sparse single-qubit measurement DAGs...") + if pauli_tracker.measurements[node][1] in non_clifford_gate_codes + for predecessor in pauli_tracker.cond_paulis[node][1] + push!(static_dag[node], predecessor) + end + for predecessor in pauli_tracker.cond_paulis[node][2] + push!(pushable_dag[node], predecessor) + end + end + if pauli_tracker.measurements[node][1] == H_code + for predecessor in pauli_tracker.cond_paulis[node][1] + push!(pushable_dag[node], predecessor) + end + end + if pauli_tracker.measurements[node][1] == I_code + for predecessor in pauli_tracker.cond_paulis[node][2] + push!(pushable_dag[node], predecessor) + end + end + end + + if final_depth == 1 + for node in VerboseIterator(nodes_to_include, verbose, "Densifying single-qubit measurement DAG...") + union!(pushable_dag[node], static_dag[node]) + end + return pushable_dag + end + + pushable_dag = get_reversed_dag(pushable_dag, verbose) + static_dag = get_reversed_dag(static_dag, verbose) + + function dag_densifier(control::Qubit, depth::Int) + if depth == 0 + return control + end + + sucessors = Set{Qubit}(static_dag[control]) + for target in pushable_dag[control] + union!(sucessors, dag_densifier(target, depth - 1)) + end + + return sucessors + end + + densified_dag::Vector{Vector{Qubit}} = [[] for _ in range(1, pauli_tracker.n_nodes)] + for node in VerboseIterator(nodes_to_include, verbose, "Densifying single-qubit measurement DAG...") + densified_dag[node] = collect(dag_densifier(node, final_depth)) + end + + return get_reversed_dag(densified_dag, verbose) +end + +""" +Given a "base node" which is measured in the T basis, find all the nodes which +depend on it. This is done by following the X edges up the tree. We go up the tree +using the following logic: + +Measured in T basis: Is the node measured in a non-clifford basis or a graph output node? +is base: Is this node where this part of the dependency graph starts? +is x target: Is this node the target of an conditional Pauli X? + +non-clifford measurement? | is base? | is x target? | What to do? + y | y | y | Follow x edges up the tree + y | y | n | do nothing, this node has no dependencies + y | n | y | Follow z edges up the tree, add self to predecessors + y | n | n | Follow z edges up the tree, add self to predecessors + n | y | y | do nothing, this node has no dependencies + n | y | n | do nothing, this node has no dependencies + n | n | y | Follow non-trivial edges up the tree, add self to predecessors + n | n | n | Follow non-trivial edges up the tree, add self to predecessors + +Attributes: + pauli_tracker (PauliTracker): The PauliTracker object containing the + information on the conditional Pauli operators and measurements + performed on each qubit. + target (Qubit): The qubit which we are finding the predecessors of. + predecessors (Set{Qubit}): The set of predecessors which we have found so far. + is_base (bool): Whether the current node is the base node. +Returns: + predecessors (Set{Qubit}): All the nodes which depend on the base node. +""" +function optimal_dag_filler_factory(pauli_tracker, output_nodes_set) + @memoize function fill_dag_for_this_node(target::Qubit) + predecessors = Set{Qubit}(target) + if pauli_tracker.measurements[target][1] in non_clifford_gate_codes || target in output_nodes_set + for predecessor in pauli_tracker.cond_paulis[target][2] + union!(predecessors, fill_dag_for_this_node(predecessor)) + end + else + # We always insert a hadamard gate before the measurement + # so we must follow the x edges up the tree for H_code + # and z edges up the tree for I_code. + if pauli_tracker.measurements[target][1] == H_code + for predecessor in pauli_tracker.cond_paulis[target][1] + union!(predecessors, fill_dag_for_this_node(predecessor)) + end + elseif pauli_tracker.measurements[target][1] == I_code + for predecessor in pauli_tracker.cond_paulis[target][2] + union!(predecessors, fill_dag_for_this_node(predecessor)) + end + end + end + + return predecessors + end + return fill_dag_for_this_node +end + +""" +Create the DAG representing the order in which measurements need to be made. +The only measurements which have to be made in order are the non-clifford ones. +So for each non-clifford measurement, we find the nodes which depend on it +and add them to the DAG. We then repeat this process for each node in the DAG +until we have found all of the nodes which need to be measured. This results +in a DAG with the minimal number of edges. Although this same DAG can be +created by calling get_dag with final_depth = inf, this function is much faster +because it doesn't have to recalculate the DAG for each node in the graph. + +Attributes: + pauli_tracker (PauliTracker): The PauliTracker object containing the + information on the conditional Pauli operators and measurements + performed on each qubit. + output_nodes (Vector{Qubit}): The nodes which are outputs of the graph. + nodes_to_include (Vector{Qubit}): The nodes which should be included + in the DAG. + +Returns: + optimal_dag (Vector{Vector{Qubit}}): A vector containing the order in + which the qubits must be measured. The first index is the layer, + and the vector contained in that index is the qubits in that + layer. The qubits in each layer are measured in parallel. +""" +function get_optimal_measurement_dag( + pauli_tracker::PauliTracker, + output_nodes, + nodes_to_include, + verbose, +)::Vector{Vector{Qubit}} + optimal_dag = [[] for _ in range(1, pauli_tracker.n_nodes)] + output_nodes_set = Set(output_nodes) + fill_dag_for_this_node = optimal_dag_filler_factory(pauli_tracker, output_nodes_set) + + for node in VerboseIterator(nodes_to_include, verbose, "Creating optimal single-qubit measurement DAG...") + non_clifford_measurement = pauli_tracker.measurements[node][1] in non_clifford_gate_codes + if non_clifford_measurement || node in output_nodes_set + predecessors = Set([]) + for predecessor in pauli_tracker.cond_paulis[node][1] + union!(predecessors, fill_dag_for_this_node(predecessor)) + end + optimal_dag[node] = collect(predecessors) + end + end + + return optimal_dag +end + +function get_reversed_dag(dag::Vector{Vector{Qubit}}, verbose::Bool=false)::Vector{Vector{Qubit}} + n = length(dag) # Number of nodes in the DAG + reversed_dag::Vector{Vector{Qubit}} = [[] for _ in 1:n] + + for (node, adjNodes) in enumerate(VerboseIterator(dag, verbose, "Reversing measurement DAG...")) + for adjNode in adjNodes + push!(reversed_dag[adjNode], node) + end + end + + return reversed_dag +end \ No newline at end of file diff --git a/src/benchq/compilation/graph_states/pauli_tracker/dag_layering.jl b/src/benchq/compilation/graph_states/pauli_tracker/dag_layering.jl new file mode 100644 index 00000000..d1c97cf8 --- /dev/null +++ b/src/benchq/compilation/graph_states/pauli_tracker/dag_layering.jl @@ -0,0 +1,393 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +""" +Given a pauli tracker and an ASG, calculate the order in which qubits +have to be measured. This is done by creating a DAG of the qubits which +depend on each other. We then find a layering of this DAG based on the +layering_optimization parameter. The layering is then stored in the +pauli_tracker object. + +Attributes: + pauli_tracker (PauliTracker): The PauliTracker object containing the + information on the conditional Pauli operators and measurements + performed on each qubit. + asg (ASG): The ASG object containing the information on the circuit. + ignored_nodes (Vector{Qubit}): The nodes which should be ignored when + calculating the layering. This is used when calculating the + layering for a subgraph. +""" +function calculate_layering!(pauli_tracker::PauliTracker, asg, ignored_nodes::Set{Qubit}, verbose::Bool=false) + verbose && println("Scheduling single qubit measurements...") + nodes_to_include = Vector{Qubit}([node for node = 1:pauli_tracker.n_nodes if !(node in ignored_nodes)]) + output_nodes = asg.stitching_properties.graph_output_nodes + + if pauli_tracker.use_fully_optimized_dag + optimal_dag = get_optimal_measurement_dag(pauli_tracker, output_nodes, nodes_to_include, verbose) + else + optimal_dag = get_dag(pauli_tracker, nodes_to_include, pauli_tracker.optimal_dag_density, verbose) + end + + if pauli_tracker.layering_optimization == "Time" + verbose && println("Calculating time optimal layering...") + + output_nodes = asg.stitching_properties.graph_output_nodes + reverse_dag = get_reversed_dag(optimal_dag, verbose) + + pauli_tracker.layering = + longest_path_layering(optimal_dag, reverse_dag, pauli_tracker.n_nodes, nodes_to_include, verbose) + elseif pauli_tracker.layering_optimization == "Space" + verbose && println("Calculating space optimized layering...") + + sparse_dag = get_dag(pauli_tracker, nodes_to_include, 1, verbose) + reverse_dag = get_reversed_dag(sparse_dag, verbose) + + pauli_tracker.layering = + variable_num_qubits(sparse_dag, reverse_dag, optimal_dag, asg, 1, nodes_to_include, verbose) + elseif pauli_tracker.layering_optimization == "Variable" + verbose && println("Calculating layering with $(pauli_tracker.max_num_qubits) qubits...") + + sparse_dag = get_dag(pauli_tracker, nodes_to_include, 1, verbose) + reverse_dag = get_reversed_dag(sparse_dag) + + pauli_tracker.layering = variable_num_qubits( + sparse_dag, + reverse_dag, + optimal_dag, + asg, + pauli_tracker.max_num_qubits, + nodes_to_include, + verbose, + ) + else + error("$(pauli_tracker.layering_optimization) is not a valid layering optimization.") + end + + verbose && println("Layering complete.") +end + +""" +A depth first search which returns the nodes in the order that they are +visited. This is used to find a topological ordering of a graph quickly +when the ordering does not matter. +""" +function depth_first_sort(measurement_dag, n_nodes, nodes_to_include, verbose::Bool=false) + visited = falses(length(measurement_dag)) + ordering = [] + stack = [] + nodes_to_include_vector = collect(Set(nodes_to_include)) + + # println("made it to cycle detection!") + # println("contains cycle: ", detect_cycle(measurement_dag)) + + for vertex in VerboseIterator(nodes_to_include_vector, verbose, "Performing depth first sort...") + if !visited[vertex] + push!(stack, vertex) + while !isempty(stack) + v = stack[end] + if visited[v] + pop!(stack) # Remove element that is fully processed + continue + end + all_visited = true + for neighbor in measurement_dag[v] # reverse to maintain correct order in result + if !visited[neighbor] + all_visited = false + push!(stack, neighbor) + end + end + if all_visited + visited[v] = true + push!(ordering, v) + pop!(stack) + end + end + end + end + + return ordering + + + + # function dfs() + # while !isempty(stack) + # node = pop!(stack) + # if visited[node] + # continue + # end + # visited[node] = true + # push!(ordering, node) + # for neighbor in measurement_dag[node] + # if !visited[neighbor] + # push!(stack, neighbor) + # end + # end + # end + # # visited[node] = true + # # for neighbor in measurement_dag[node] + # # if !visited[neighbor] + # # dfs(neighbor) + # # end + # # end + # # push!(ordering, node) + # end + + # for node in VerboseIterator(nodes_to_include, verbose, "Performing depth first sort...") + # if !visited[node] + # push!(stack, node) + # dfs() + # end + # end + + # return ordering +end + + +function detect_cycle(measurement_dag) + n = length(measurement_dag) + white_set = Set(1:n) # All nodes are initially unvisited + gray_set = Set() + black_set = Set() + num_recursions = 0 + + function dfs_cycle_detect(node) + num_recursions += 1 + println("Recursion number: ", num_recursions) + push!(gray_set, node) # Add node to gray set + delete!(white_set, node) # Remove node from white set + + for neighbor in measurement_dag[node] + if neighbor in black_set + continue # Neighbor already completely processed + elseif neighbor in gray_set + num_recursions -= 1 + return true # Cycle found + elseif dfs_cycle_detect(neighbor) + num_recursions -= 1 + return true + end + end + + push!(black_set, node) # Add node to black set + delete!(gray_set, node) # Remove node from gray set + num_recursions -= 1 + return false + end + + for node in 1:n + if node in white_set && dfs_cycle_detect(node) + return true + end + end + + return false # No cycles found +end + + +""" +Create the layering based on the longest path in the DAG. This is done by +finding the longest path from a source to each node. The layer of each node +is then determined by the longest path from a source. + +Attributes: + measurement_dag (Vector{Vector{Qubit}}): A dependency graph of which qubits + need to be measured before which other qubits. The first index + is the qubit which needs to be measured, and the vector contained + in that index is the qubits which need to be measured before it. + n_nodes (Qubit): The number of qubits in the circuit. + nodes_to_include (Vector{Qubit}): The nodes which should be included + in the DAG. + +Returns: + layers (Vector{Vector{Qubit}}): The layer of each node in the DAG. +""" +function longest_path_layering(measurement_dag, reverse_measurent_dag, n_nodes, nodes_to_include::Vector{Qubit}, verbose::Bool=false) + longest_path = zeros(Qubit, n_nodes) + nodes_to_include = Set(nodes_to_include) + nodes_to_include_vector = collect(nodes_to_include) + + sorted_nodes = depth_first_sort(reverse_measurent_dag, n_nodes, nodes_to_include_vector, verbose) + + final_layer = 0 + for u in VerboseIterator(sorted_nodes, verbose, "Assigning path lengths...") + for v in measurement_dag[u] + if v in nodes_to_include + longest_path[v] = max(longest_path[v], longest_path[u] + 1) + end + end + end + final_layer = maximum(longest_path) + + layers = [[] for _ in range(1, final_layer + 1)] + for node in VerboseIterator(nodes_to_include_vector, verbose, "Layering based on path lengths...") + # correct for reverse layering given by above + corrected_layer = final_layer - longest_path[node] + 1 + append!(layers[corrected_layer], node) + end + + return layers +end + + + +""" +Kahn's algorithm for topological sorting. This is used to find the layering +of the DAG for the variable width optimization. We also choose to prioritize +nodes with the smallest neighborhoods first, as this tends to produce better +results as it allows for all the neighbors of a highly connected node to be +measured before the highly connected node. + +Attributes: + measurement_dag (Vector{Vector{Qubit}}): A dependency graph of which qubits + need to be measured before which other qubits. The first index + is the qubit which needs to be measured, and the vector contained + in that index is the qubits which need to be measured before it. + For example, measurement_dag[3] = [6, 7] means that we must measure + qubits 6 and 7 before qubit 3. + n_nodes (Qubit): The number of qubits in the circuit. + nodes_to_include (Vector{Qubit}): The nodes which should be included + in the measurement DAG. + asg (AlgorithmSpecificGraph): The ASG object containing the information of the + prepared state's conectivity. +""" +function kahns_algorithm( + measurement_dag::Vector{Vector{Qubit}}, + reverse_measurent_dag::Vector{Vector{Qubit}}, + n_nodes::Qubit, + nodes_to_include::Vector{Qubit}, + asg, + verbose::Bool=false, +)::Vector{Qubit} + in_degree = zeros(Int, n_nodes) + for node in nodes_to_include + in_degree[node] = length(measurement_dag[node]) + end + + queue = Vector{Qubit}([]) + for node in nodes_to_include + if in_degree[node] == 0 + push!(queue, node) + end + end + # start with nodes that require the smallest neighborhoods + # sort!(queue, by=x -> length(asg.edge_data[x])) + + ordering = Vector{Qubit}([]) + remaining_node_degrees = [length(asg.edge_data[node]) for node in 1:asg.n_nodes] + + if verbose + println("Performing topological sort via Kahn's Algorithm...") + total_length = length(in_degree) + counter = dispcnt = 0 + start_time = time() + end + + while !isempty(queue) + # add nodes with the smallest neighborhoods first. This will help + # measure the nodes with the larger neighborhoods later, which + # will cut down on the number of nodes that need to be added to + # measure the large nodes. + node = queue[1] + min_pos = 1 + min_node_cost = 1000000000 + # Calculate which qubits would exist if we added this node + for (pos, possible_node) in enumerate(queue) + possible_node_cost = remaining_node_degrees[possible_node] + if possible_node_cost < min_node_cost + node = possible_node + min_pos = pos + min_node_cost = possible_node_cost + end + if min_node_cost < 1 + break + end + end + deleteat!(queue, min_pos) + + push!(ordering, node) + for neighbor in reverse_measurent_dag[node] + in_degree[neighbor] -= 1 + if in_degree[neighbor] == 0 + push!(queue, neighbor) + end + end + for neighbor in asg.edge_data[node] + remaining_node_degrees[neighbor] -= 1 + end + + # Show progress in real time + if verbose + counter += 1 + dispcnt += 1 + if dispcnt >= 1000 + percent = round(Int, 100 * counter / total_length) + elapsed_time = round(time() - start_time, digits=2) + print("\r$(percent)% ($counter) completed in $(elapsed_time)s") + dispcnt = 0 # Reset display counter + end + end + end + + if verbose + elapsed = round(time() - start_time, digits=2) + println("\r100% ($counter) completed in $erase_line$(elapsed)s") + end + + return ordering +end + +function get_new_num_node_after_adding_qubit(new_qubit, asg, curr_physical_nodes, measured_nodes) + new_nodes_to_add = setdiff(get_neighborhood(new_qubit, asg), measured_nodes) + return length(union(curr_physical_nodes, new_nodes_to_add)) +end + +""" +Given a DAG, finds layering in the dag which minimizes the width due to +the ASG adding nodes to the DAG. This is done by first finding a topological +ordering of the DAG which minimizes which minimizes the number of qubits. +Next, we combine layers of the DAG such that that minimum number of qubits +is not increased. +""" +function variable_num_qubits(measurement_dag, reverse_measurent_dag, optimal_dag, asg, num_qubits::Int, nodes_to_include::Vector{Qubit}, verbose::Bool=false) + space_optimized = num_qubits == 1 + sorted_nodes = kahns_algorithm(measurement_dag, reverse_measurent_dag, asg.n_nodes, nodes_to_include, asg, verbose) + + # create a layering that is just the topological sort + ordering_layering = [] + for node in sorted_nodes + push!(ordering_layering, [node]) + end + min_logical_qubits = get_num_logical_qubits(ordering_layering, asg, "Space", verbose) + + if space_optimized + num_qubits = min_logical_qubits + elseif num_qubits < min_logical_qubits + @warn "Cannot fit circuit onto $num_qubits qubits. Setting num qubits to $min_logical_qubits." + end + + curr_physical_nodes = get_neighborhood(ordering_layering[1], asg) + measured_nodes = Set{Qubit}([]) + + curr_layer = Vector{Qubit}([sorted_nodes[1]]) + layering = Vector{Vector{Qubit}}([]) + for new_node_to_add in VerboseIterator( + sorted_nodes[2:end], + verbose, + "Combining adjacent timesteps without increasing qubit number...", + ) + new_neighborhood_to_add = setdiff(get_neighborhood(new_node_to_add, asg), measured_nodes) + union!(curr_physical_nodes, new_neighborhood_to_add) + + if length(curr_physical_nodes) <= num_qubits && isempty(intersect(optimal_dag[new_node_to_add], curr_physical_nodes)) + push!(curr_layer, new_node_to_add) + else + push!(layering, curr_layer) + union!(measured_nodes, curr_layer) + setdiff!(curr_physical_nodes, curr_layer) + curr_layer = [new_node_to_add] + end + end + push!(layering, curr_layer) + + return layering +end \ No newline at end of file diff --git a/src/benchq/compilation/graph_states/pauli_tracker/dag_layering_properties.jl b/src/benchq/compilation/graph_states/pauli_tracker/dag_layering_properties.jl new file mode 100644 index 00000000..588d4fff --- /dev/null +++ b/src/benchq/compilation/graph_states/pauli_tracker/dag_layering_properties.jl @@ -0,0 +1,109 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +""" +Get the number of logical qubits in the circuit. This is done by finding +the maximum number of physical qubits which are connected to each other +through the conditional Pauli operators at each layer of the pauli tracker. +""" +function get_num_logical_qubits(layering, asg, optimization, verbose=false) + if optimization == "Space" + neighborhod_degree = 1 + elseif optimization == "Time" + neighborhod_degree = 2 + elseif optimization == "Variable" + neighborhod_degree = 1 + else + throw(ArgumentError("Invalid optimization type.")) + end + + curr_physical_nodes = get_neighborhood(layering[1], asg, neighborhod_degree) + n_logical_qubits = length(curr_physical_nodes) + measured_nodes = Set{Qubit}([]) + + for i in VerboseIterator(1:length(layering)-1, verbose, "Calculating number of logical qubits...") + union!(measured_nodes, layering[i]) + added_nodes = layering[i+1] + + setdiff!(curr_physical_nodes, layering[i]) + new_nodes_to_add = setdiff(get_neighborhood(added_nodes, asg, neighborhod_degree), measured_nodes) + union!(curr_physical_nodes, new_nodes_to_add) + + n_logical_qubits = max(n_logical_qubits, length(curr_physical_nodes)) + end + + return n_logical_qubits +end + +function get_neighborhood(centers, asg, distance=1) + neighborhood = Set{Qubit}([]) + if distance == 0 + return centers + end + for center in centers + for neighbor in asg.edge_data[center] + push!(neighborhood, neighbor) + end + end + + return get_neighborhood(union(neighborhood, centers), asg, distance - 1) +end + +function get_n_measurement_steps(pauli_tracker::PauliTracker) + return length(pauli_tracker.layering) +end + + +""" +Get the lower bound for the number of logical qubits in the circuit. This is done by finding +the maximum number of nodes which are in the neighborhod of a node, yet must be measured after +that node. We know that when we measure the node at the center of the neighborhood, all of the +nodes which are measured after that must be realized as logical qubits. The function will print +out the bound as well as histogram of the bounds for each node. + +Attributes: + dag (Vector{Vector{Qubit}}): The DAG representing the order in which the qubits must be measured. + asg (AbstractStateGraph): The state graph representing the connectivity of the qubits. + nodes_to_include (Vector{Qubit}): The nodes which should be included in the DAG. + depth (Int): The depth to which the successors of each node should be calculated. + verbose (Bool): Whether to print the progress of the function. + +Returns: + nothing +""" +function print_lower_bound_for_n_logical_qubits(dag, asg, nodes_to_include, depth=5, verbose=false) + bounds = [0 for _ in 1:asg.n_nodes] + reverse_dag = get_reversed_dag(dag) + for qubit in VerboseIterator(nodes_to_include, verbose, "Calculating logical qubit lower bound...") + successors = get_all_successors(reverse_dag, qubit, depth) + bounds[qubit] = length(intersect(asg.edge_data[qubit], successors)) + end + println("Lower bound on logical qubits with this DAG and ASG: ", maximum(bounds)) + println("Number of nodes with each bound: ", bounds_histogram(bounds)) +end + +function get_all_successors(dag, qubit, depth) + + @memoize function get_successors(qubit, depth) + if depth == 0 + return Set{Qubit}() + end + + successors = Set{Qubit}(dag[qubit]) + for node in dag[qubit] + union!(successors, get_successors(node, depth - 1)) + end + + return successors + end + + return get_successors(qubit, depth) +end + +function bounds_histogram(bounds) + hist = Dict{Int,Int}() + for bound in bounds + hist[bound] = get(hist, bound, 0) + 1 + end + return hist +end \ No newline at end of file diff --git a/src/benchq/compilation/graph_states/pauli_tracker/pauli_tracker.jl b/src/benchq/compilation/graph_states/pauli_tracker/pauli_tracker.jl new file mode 100644 index 00000000..95b5df36 --- /dev/null +++ b/src/benchq/compilation/graph_states/pauli_tracker/pauli_tracker.jl @@ -0,0 +1,218 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +""" +Holds data for tracking conditional Pauli operators through a circuit. + + cond_paulis: Vector{Vector{Vector{Qubit}}} + A vector containing the information on the conditional paulis + for each qubit. The first index is the qubit which the pauli is + conditioned on, the second index is the type of pauli (1 for X, + 2 for Z). The innermost vector is the list of target qubit indices. + For example, cond_paulis[3][1] = [6, 7] means that we must + apply an X gate to qubits 6 and 7 if qubit 3 is measured to be 1. + measurements: Vector{Vector{Union{UInt8,Float64}}} + A vector containing the information on the basis in which each + qubit is measured. We assume that two operations will be applied before + measurement in the Z basis: the first is specified by this array and the second + is always a Hadamard gate. The first index of the measurements array is the + qubit index, and the vector contained in that index describes the operation to + be applied before the Hadamard. The first element is the tye of operation, and + if the operation is an RZ, then the second element is the phase of the RZ gate. + If the operation is not an RZ, the second element is zero. + For example, measurements[3] = [H_code, 0.0] means that we must apply two H + gates (i.e. identity) to qubit 3 before measurement and + measurements[3] = [RZ_code, 0.5] means that we must apply RZ(0.5) followed by H + before measurement. + n_nodes: Qubit + The number of qubits in the circuit. + layering: Vector{Vector{Qubit}} + A vector containing order in which the qubits must be measured. + The first index is the layer, and the vector contained in that + index is the qubits in that layer. The qubits in each layer are + measured in parallel. + layering_optimization: String + The optimization used to calculate the layering. Can be "Time", + "Space", and "Variable". + max_num_qubits: Int + The width parameter used for the "Variable" optimization. Corresponds + to the maximum number of qubits which can exist at each time step. + Note that if one picks max_num_qubits to be too small, we will + resort to the smallest width which can fit the circuit. + optimal_dag_density: Int + The optimal density of the DAG. This quantity roughly corresponds to + how well defined the "arrow of time" is in the DAG. A higher number + means that the DAG is less well defined and so the DAG might be more + difficult to create, but is more optimizable. Ranges from 0-infinity. + This variable is used in every dag optimizeation other than +""" +mutable struct PauliTracker + cond_paulis::Vector{Vector{Vector{Qubit}}} + measurements::Vector{Vector{Union{UInt8,Float64}}} + n_nodes::Qubit + layering::Vector{Vector{Qubit}} + layering_optimization::String + max_num_qubits::Int + optimal_dag_density::Int + use_fully_optimized_dag::Bool + + PauliTracker(cond_paulis, measurements, n_nodes, layering, layering_optimization, max_num_qubits, optimal_dag_density, use_fully_optimized_dag) = new( + cond_paulis, + measurements, + n_nodes, + layering, + layering_optimization, + max_num_qubits, + optimal_dag_density, + use_fully_optimized_dag, + ) + + PauliTracker(n_qubits, layering_optimization, max_num_qubits, optimal_dag_density, use_fully_optimized_dag) = new( + [[[], []] for _ in range(1, n_qubits)], + [[H_code, 0.0] for _ in range(1, n_qubits)], + n_qubits, + [], + layering_optimization, + max_num_qubits, + optimal_dag_density, + use_fully_optimized_dag, + ) +end + +function Base.show(io::IO, pt::PauliTracker) + # Helper function to convert nested Qubit vectors to decimal format + function convert_to_decimal(v) + if typeof(v) == Qubit + return Int(v) # Convert Qubit to Int for decimal printing + elseif typeof(v) <: AbstractVector + return [convert_to_decimal(e) for e in v] # Recursively convert elements + else + return v # Return non-vector elements unchanged + end + end + + print(io, "PauliTracker(\n") + print(io, " cond_paulis = $(convert_to_decimal(pt.cond_paulis)),\n") + print(io, " measurements = $(pt.measurements),\n") # Assumes measurements are already in a printable format + print(io, " n_nodes = $(Int(pt.n_nodes)),\n") # Convert n_nodes to Int for decimal printing + print(io, " layering = $(convert_to_decimal(pt.layering)),\n") + print(io, " layering_optimization = \"$(pt.layering_optimization)\",\n") + print(io, " max_num_qubits = $(pt.max_num_qubits),\n") + print(io, " optimal_dag_density = $(pt.optimal_dag_density),\n") + print(io, " use_fully_optimized_dag = $(pt.use_fully_optimized_dag)\n") + print(io, ")") +end + +"""Convert pauli tracker to a python object""" +function python_pauli_tracker(pauli_tracker) + python_cond_paulis = [] + for node in pauli_tracker.cond_paulis + push!(python_cond_paulis, pylist([pylist(node[1] .- 1), pylist(node[2] .- 1)])) + end + + python_pauli_tracker = Dict( + "cond_paulis" => pylist(python_cond_paulis), + "measurements" => pylist(pauli_tracker.measurements), + "n_nodes" => pauli_tracker.n_nodes, + "layering" => python_adjlist!(pauli_tracker.layering), + "layering_optimization" => pauli_tracker.layering_optimization, + "max_num_qubits" => pauli_tracker.max_num_qubits, + "optimal_dag_density" => pauli_tracker.optimal_dag_density, + "use_fully_optimized_dag" => pauli_tracker.use_fully_optimized_dag, + ) + + return python_pauli_tracker +end + +function add_new_qubit_to_pauli_tracker!(pauli_tracker::PauliTracker) + push!(pauli_tracker.cond_paulis, [[], []]) + push!(pauli_tracker.measurements, [H_code, 0.0]) + pauli_tracker.n_nodes += 1 +end + +""" +Add a conditional Pauli operator to the PauliTracker object. +""" + +function add_z_to_pauli_tracker!( + cond_paulis::Vector{Vector{Vector{Qubit}}}, + control_qubit::Qubit, + target_qubit::Qubit, +) + push!(cond_paulis[target_qubit][2], control_qubit) +end + +function add_x_to_pauli_tracker!( + cond_paulis::Vector{Vector{Vector{Qubit}}}, + control_qubit::Qubit, + target_qubit::Qubit, +) + push!(cond_paulis[target_qubit][1], control_qubit) +end + +""" +Indicate that a node is being measured. +""" + +function add_measurement!(measurements, op_code::UInt8, qubit::Qubit) + measurements[qubit][1] = op_code +end + +function add_measurement!(measurements, op_code::UInt8, qubit::Qubit, phase::Float64) + measurements[qubit][1] = op_code + measurements[qubit][2] = phase +end + +""" +Functions for tracking the paulis through gates. +""" + +function track_conditional_paulis_through_h( + cond_paulis::Vector{Vector{Vector{Qubit}}}, + qubit, +) + x_cond_paulis = cond_paulis[qubit][1] + cond_paulis[qubit][1] = cond_paulis[qubit][2] + cond_paulis[qubit][2] = x_cond_paulis +end + +function track_conditional_paulis_through_s( + cond_paulis::Vector{Vector{Vector{Qubit}}}, + qubit, +) + for x_control in cond_paulis[qubit][1] + toggle_pauli_z(cond_paulis, x_control, qubit) + end + + +end + +function track_conditional_paulis_through_cz( + cond_paulis::Vector{Vector{Vector{Qubit}}}, + qubit_1, + qubit_2, +) + for x_control in cond_paulis[qubit_1][1] + toggle_pauli_z(cond_paulis, x_control, qubit_2) + end + for x_control in cond_paulis[qubit_2][1] + toggle_pauli_z(cond_paulis, x_control, qubit_1) + end +end + +""" +If a controlled Z exists on the target qubit, then we get rid of it. +If a controlled Z doesn't exist on the target qubit, then we add one. +""" +function toggle_pauli_z(cond_paulis, toggled_qubit, target_qubit) + if toggled_qubit in cond_paulis[target_qubit][2] + setdiff!(cond_paulis[target_qubit][2], [toggled_qubit]) + else + push!(cond_paulis[target_qubit][2], toggled_qubit) + end +end + + +include("dag_creation.jl") +include("dag_layering.jl") +include("dag_layering_properties.jl") \ No newline at end of file diff --git a/src/benchq/compilation/graph_states/ruby_slippers/algorithm_specific_graph.jl b/src/benchq/compilation/graph_states/ruby_slippers/algorithm_specific_graph.jl new file mode 100644 index 00000000..2c74b902 --- /dev/null +++ b/src/benchq/compilation/graph_states/ruby_slippers/algorithm_specific_graph.jl @@ -0,0 +1,158 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +""" +The current stitching properties of an ASG. This is used to keep track of +whether the ASG can be concatenated with other ASGs or if one can add gates +to the ASG. If takes_input is true, then one can concatenate this ASG after +previous asg. If gives output is true, then one can concatenate an ASG after +this one by connecting the output_nodes. + +Attributes: + takes_graph_input (bool): Whether the ASG can be concatenated after another ASG. + gives_graph_output (bool): Whether the ASG can be concatenated before another ASG. + graph_input_nodes (Vector{Qubit}): Nodes which are connected to the output nodes + of a previous graph in order to make a concatenated graph with this graph + second and the other graph first. If takes_graph_input is false, graph_input_nodes + will be an empty vector. + graph_output_nodes (Vector{Qubit}): Nodes which are connected to the input nodes + of the next graph in order to make a concatenated graph with this graph + first and the other graph second. If gives_graph_output is false, output_nodes + will be an empty vector. + gate_output_nodes (Vector{Qubit}): Nodes which can be acted upon by the + GraphSim algorthm. That is, individual gates can act on these nodes, + but they cannot be used to concatenate graphs. Because of this, if + gives_graph_output is true, then gate_output_nodes is the last qubits + that the gates acted on before creating the output nodes. +""" +mutable struct StitchingProperties + takes_graph_input::Bool + gives_graph_output::Bool + graph_input_nodes::Vector{Qubit} + graph_output_nodes::Vector{Qubit} + gate_output_nodes::Vector{Qubit} +end +StitchingProperties(takes_graph_input, gives_graph_output, n_qubits) = StitchingProperties( + takes_graph_input, + gives_graph_output, + [], + [], + [Qubit(i) for i = 1:n_qubits] +) + +function Base.show(io::IO, sp::StitchingProperties) + decimal_graph_input_nodes = [Int(qubit) for qubit in sp.graph_input_nodes] + decimal_graph_output_nodes = [Int(qubit) for qubit in sp.graph_output_nodes] + decimal_gate_output_nodes = [Int(qubit) for qubit in sp.gate_output_nodes] + print(io, "StitchingProperties(\n " * + "takes_graph_input = $(sp.takes_graph_input),\n " * + "gives_graph_output = $(sp.gives_graph_output),\n " * + "graph_input_nodes = $(decimal_graph_input_nodes),\n " * + "graph_output_nodes = $(decimal_graph_output_nodes),\n " * + "gate_output_nodes = $(decimal_gate_output_nodes)\n )" + ) +end + +function python_stitching_properties(stitching_properties::StitchingProperties) + return Dict( + "takes_graph_input" => stitching_properties.takes_graph_input, + "gives_graph_output" => stitching_properties.gives_graph_output, + "graph_input_nodes" => pylist(stitching_properties.graph_input_nodes .- 1), + "graph_output_nodes" => pylist(stitching_properties.graph_output_nodes .- 1), + "gate_output_nodes" => pylist(stitching_properties.gate_output_nodes .- 1) + ) +end + +""" +Hyperparameters which can be used to speed up the compilation. + +Attributes: + teleportation_threshold::Int max node degree allowed before state is teleported + teleportation_distance::Int number of teleportations to do when state is teleported + min_neighbor_degree::Int stop searching for neighbor with low degree if + neighbor has at least this many neighbors + max_num_neighbors_to_search::Int max number of neighbors to search through when finding + a neighbor with low degree + decomposition_strategy::Int strategy for decomposing non-clifford gate + 0: keep current qubit as data qubit + 1: teleport data to new qubit which becomes data qubit +""" +struct RbSHyperparams + teleportation_threshold::UInt16 + teleportation_distance::UInt8 + min_neighbor_degree::UInt8 + max_num_neighbors_to_search::UInt32 + decomposition_strategy::UInt8 # TODO: make pauli tracker work witn decomposition_strategy=1 +end + +default_hyperparams = RbSHyperparams(40, 4, 6, 1e5, 0) +# Hyperparameter choices which disallow teleportation in the compilation +graphsim_hyperparams(min_neighbor_degree, max_num_neighbors_to_search) = RbSHyperparams(65535, 2, min_neighbor_degree, max_num_neighbors_to_search, 0) +default_graphsim_hyperparams = graphsim_hyperparams(6, 1e5) + + +""" +Data on the aglortihm specific graph state. During computation, this +struct may contain more nodes than are actually used in the graph state. +At the end of the computation, the data structures are resized to only +contain the nodes which are actually used in the graph state. A lack +of input and output nodes indicate that this graph is not stitchable. + +Attributes: + edge_data (Vector{AdjList}): adjacency list describing the graph + sqs (Vector{UInt8}): single qubit clifford symplectic operations + on each node. The symplectic operations are + just the clifford operators modulo the paulis + sqp (Vector{UInt8}): single qubit pauli operations on each node + n_nodes (UInt32): number of nodes being used by the graph state + stitching_properties (Uint32): data on the stitchability of the graph +""" +mutable struct AlgorithmSpecificGraph + edge_data::Vector{AdjList} + sqs::Vector{UInt8} + sqp::Vector{UInt8} + n_nodes::UInt32 + stitching_properties::StitchingProperties +end + +function Base.show(io::IO, ag::AlgorithmSpecificGraph) + # Convert edge_data to Int for decimal printing + decimal_edge_data = [[Int(qubit) for qubit in adjList] for adjList in ag.edge_data] + print(io, "AlgorithmSpecificGraph(\n " * + "edge_data = $decimal_edge_data,\n " * + "sqs = $(ag.sqs),\n " * + "sqp = $(ag.sqp),\n " * + "n_nodes = $(ag.n_nodes),\n " * + "stitching_properties = " + ) + show(io, ag.stitching_properties) # Use custom show method for readability + println(io, "\n)") +end + +# Create a graph with all qubits initialized to the |0> state. +AlgorithmSpecificGraphAllZero(max_graph_size, n_qubits) = AlgorithmSpecificGraph( + [AdjList() for _ = 1:max_graph_size], + fill(H_code, max_graph_size), + fill(I_code, max_graph_size), + n_qubits, + StitchingProperties(false, false, n_qubits), +) + +""" +Destructively convert edge_data to python adjacency list format. +""" +function python_adjlist!(adj) + pylist([pylist(adj[i] .- 1) for i = eachindex(adj)]) +end + +function python_asg(asg) + python_asg = Dict( + "edge_data" => python_adjlist!(asg.edge_data), + "sqs" => pylist(asg.sqs), + "sqp" => pylist(asg.sqp), + "data_nodes" => pylist(asg.stitching_properties.gate_output_nodes .- 1), + "n_nodes" => asg.n_nodes, + "stitching_properties" => python_stitching_properties(asg.stitching_properties), + ) + return python_asg +end \ No newline at end of file diff --git a/src/benchq/compilation/graph_states/ruby_slippers/asg_stitching.jl b/src/benchq/compilation/graph_states/ruby_slippers/asg_stitching.jl new file mode 100644 index 00000000..79e8c6b3 --- /dev/null +++ b/src/benchq/compilation/graph_states/ruby_slippers/asg_stitching.jl @@ -0,0 +1,350 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +BUFFER_SIZE = 100 +if BUFFER_SIZE % 2 != 0 + error("Buffer size must be even.") +end +""" +Initialize the graph state with a buffer of teleportations for each qubit. +This allows the graph state to be stitched with other graph states before it. + +Attributes: + max_graph_size (UInt32): maximum number of nodes in the graph + n_qubits (UInt32): number of qubits in the graph + layering_optimization (Bool): whether or not to use the layering optimization + +Returns: + asg (AlgorithmSpecificGraph): graph after initialization + pauli_tracker (PauliTracker): pauli tracker for the graph +""" +function initialize_for_graph_input(max_graph_size, n_qubits, layering_optimization, max_num_qubits, optimal_dag_density, use_fully_optimized_dag) + asg = AlgorithmSpecificGraphAllZero(max_graph_size, 0) + pauli_tracker = PauliTracker(0, layering_optimization, max_num_qubits, optimal_dag_density, use_fully_optimized_dag) + for _ = 1:n_qubits + # create start to next buffer + asg.n_nodes += 1 + push!(asg.stitching_properties.gate_output_nodes, Qubit(asg.n_nodes)) + add_new_qubit_to_pauli_tracker!(pauli_tracker) + asg.sqs[asg.n_nodes] = I_code # start buffer in the |+> state + asg.sqp[asg.n_nodes] = I_code + # create a buffer of teleportations for each qubit + teleportation!( + asg, + last(asg.stitching_properties.gate_output_nodes), + pauli_tracker, + default_hyperparams, + BUFFER_SIZE, + ) + # println("data nodes: $(asg.stitching_properties.gate_output_nodes)") + end + return asg, pauli_tracker +end + +""" +Add the output nodes to the graph state by creating the beginning of +a buffer of teleportations for each qubit. This allows the graph state +to be stitched with other graph states after it. The excess nodes in the +buffer are removed from the graph state and marked to be removed by the +minimize_node_labels! function. + +This function adds two teleporations to the buffer (corresponding to adding +4 qubits to the graph state). We needed 2 teleportations to ensure that the +buffer only has hadamard gates as local symplectics. We have to preserve +the first qubit in the buffer because it contains all the pauli tracking +information that would be passed to the buffer. + +Both of these facts together prove that this stitching method is optimal +for the case of stitching two graph states together produced from ruby +slippers. More optimial stitching method might exist for other ASG +producing algorithms such as Jabalizer. + +Attributes: + asg (AlgorithmSpecificGraph): graph to be stitched + pauli_tracker (PauliTracker): pauli tracker for the graph + nodes_to_remove (Vector{UInt32}): nodes to be removed from the graph +""" +function add_output_nodes!(asg, pauli_tracker, nodes_to_remove::Set{Qubit}) + data_nodes = collect(asg.stitching_properties.gate_output_nodes) + for data_node in asg.stitching_properties.gate_output_nodes + teleportation!(asg, data_node, pauli_tracker, default_hyperparams, 4) + push!(asg.stitching_properties.graph_output_nodes, asg.n_nodes - 3) + + remove_edge!(asg.edge_data, asg.n_nodes, asg.n_nodes - 1) + remove_edge!(asg.edge_data, asg.n_nodes - 1, asg.n_nodes - 2) + remove_edge!(asg.edge_data, asg.n_nodes - 2, asg.n_nodes - 3) + + pauli_tracker.cond_paulis[asg.n_nodes] = [[], []] + pauli_tracker.cond_paulis[asg.n_nodes-1] = [[], []] + pauli_tracker.cond_paulis[asg.n_nodes-2] = [[], []] + + push!(nodes_to_remove, asg.n_nodes) + push!(nodes_to_remove, asg.n_nodes - 1) + push!(nodes_to_remove, asg.n_nodes - 2) + end + + new_graph_output_nodes = [] + for i in eachindex(data_nodes) + push!(new_graph_output_nodes, asg.stitching_properties.graph_output_nodes[i]) + push!(new_graph_output_nodes, data_nodes[i]) + end + asg.stitching_properties.graph_output_nodes = new_graph_output_nodes + + asg.stitching_properties.gate_output_nodes = [] + asg.stitching_properties.gives_graph_output = true +end + +""" +Given a graph state which has been initialized with a buffer of teleportations +for each qubit, this function finds the part of the buffer that was not consumed +during graph creation. It hen removes the connections in the unconsumed buffer nodes +and marks them to be removed from the graph state. It also dismantles the dependencies +in the pauli tracker so that the unconsumed nodes are not considered in the layering. + +Attributes: + asg (AlgorithmSpecificGraph): graph to be pruned + pauli_tracker (PauliTracker): pauli tracker for the graph + n_qubits (UInt32): number of qubits in the graph + nodes_to_remove (Vector{UInt32}): nodes to be removed from the graph +""" +function prune_buffer!(asg, pauli_tracker, n_qubits, nodes_to_remove::Set{Qubit}) + for i = 1:n_qubits + buffer_start = (i - 1) * (BUFFER_SIZE + 1) + 3 + buffer_end = i * (BUFFER_SIZE + 1) # +1 to include the data qubit + correct_sqs_start = + asg.sqs[buffer_start] == H_code && asg.sqs[buffer_start+1] == H_code + correct_sqp_start = + asg.sqp[buffer_start] == I_code && asg.sqs[buffer_start+1] == I_code + correct_adj_start = + asg.edge_data[buffer_start+1] == Set([buffer_start + 1, buffer_start - 1]) && + asg.edge_data[buffer_start] == Set([buffer_start + 1]) + if correct_sqs_start && correct_sqp_start && correct_adj_start + throw( + DomainError( + "Entire buffer was consumed! Please either:\n" + + "1. Increase the BUFFER_SIZE variable (may lead to high resource counts)\n" + + "2. Decrease the ratio of two qubit gates to T gates in your circuit.", + ), + ) + end + for j = buffer_start:2:buffer_end + adj_consumed = + asg.edge_data[j-1] != Set([j, j - 2]) || + asg.edge_data[j-2] != Set([j - 1, j - 3]) + sqs_consumed = asg.sqs[j-1] != H_code || asg.sqs[j] != H_code + sqp_consumed = asg.sqp[j-1] != I_code || asg.sqp[j] != I_code + if !adj_consumed || !sqs_consumed || !sqp_consumed + if j == buffer_end + push!(asg.stitching_properties.graph_input_nodes, j - 1) + push!(asg.stitching_properties.graph_input_nodes, j - 2) + break + end + pauli_tracker.cond_paulis[j+1] = [[], []] + pauli_tracker.cond_paulis[j] = [[], []] + pauli_tracker.cond_paulis[j-1] = [[], []] + pauli_tracker.cond_paulis[j-2] = [[], []] + remove_edge!(asg.edge_data, j, j - 1) + remove_edge!(asg.edge_data, j - 1, j - 2) + push!(nodes_to_remove, j - 1) + push!(nodes_to_remove, j - 2) + else + push!(asg.stitching_properties.graph_input_nodes, j - 1) + push!(asg.stitching_properties.graph_input_nodes, j - 2) + break + end + end + end + + asg.stitching_properties.takes_graph_input = true +end + +""" +Given some nodes which have been removed from the graph, this function +relabels the nodes in the graph to skip the removed nodes. Thus function +must run in O(n_nodes^2) time, so it's best to just to be used to test +that stitching works for small examples. + +Attributes: + asg (AlgorithmSpecificGraph): graph to be relabeled + pauli_tracker (PauliTracker): pauli tracker for the graph + nodes_to_remove (Vector{UInt32}): nodes to be removed from the graph + +Returns: + asg (AlgorithmSpecificGraph): graph after relabeling + pauli_tracker (PauliTracker): pauli tracker after relabeling +""" +function minimize_node_labels!(asg::AlgorithmSpecificGraph, pauli_tracker, nodes_to_remove) + if isempty(nodes_to_remove) + return asg, pauli_tracker + end + + nodes_to_remove = sort(collect(nodes_to_remove)) + nodes_to_keep = setdiff(1:asg.n_nodes, nodes_to_remove) + + + # relabel nodes to skip isolated nodes + for (new_node_index, old_node_index) in enumerate(nodes_to_keep) + for neighborhood in asg.edge_data + for neighbor in neighborhood + if neighbor == old_node_index + delete!(neighborhood, old_node_index) + push!(neighborhood, new_node_index) + end + end + end + asg.stitching_properties.gate_output_nodes = [ + old_node_index == node ? new_node_index : node for + node in asg.stitching_properties.gate_output_nodes + ] + asg.stitching_properties.graph_input_nodes = [ + old_node_index == node ? new_node_index : node for + node in asg.stitching_properties.graph_input_nodes + ] + asg.stitching_properties.graph_output_nodes = [ + old_node_index == node ? new_node_index : node for + node in asg.stitching_properties.graph_output_nodes + ] + end + + for i = 1:length(pauli_tracker.cond_paulis) + for j = 1:length(pauli_tracker.cond_paulis[i]) + for k = 1:length(pauli_tracker.cond_paulis[i][j]) + if pauli_tracker.cond_paulis[i][j][k] in nodes_to_remove + println(i, " ", j, " ", k) + error( + "Node $(pauli_tracker.cond_paulis[i][j][k]) was designated " * + "for relabelling but was not removed.", + ) + else + pauli_tracker.cond_paulis[i][j][k] = + findfirst(nodes_to_keep .== pauli_tracker.cond_paulis[i][j][k]) + end + end + end + end + + for i = 1:length(pauli_tracker.layering) + sublist = pauli_tracker.layering[i] + for j = eachindex(sublist) + if sublist[j] in nodes_to_keep + sublist[j] = findfirst(nodes_to_keep .== sublist[j]) + elseif sublist[j] in nodes_to_remove + error( + "Node $(sublist[j]) was designated for relabelling but was " * + "included in layering.", + ) + end + end + pauli_tracker.layering[i] = sublist + end + pauli_tracker.layering = [layer for layer in pauli_tracker.layering if !isempty(layer)] + + + # delete isolated nodes from data structures + for node in reverse(nodes_to_remove) + deleteat!(asg.edge_data, node) + deleteat!(asg.sqs, node) + deleteat!(asg.sqp, node) + deleteat!(pauli_tracker.cond_paulis, node) + deleteat!(pauli_tracker.measurements, node) + + pauli_tracker.cond_paulis[:] .= + [filter(x -> x != node, frame) for frame in pauli_tracker.cond_paulis[:]] + end + + asg.n_nodes = length(nodes_to_keep) + pauli_tracker.n_nodes = length(nodes_to_keep) + + return asg, pauli_tracker +end + + +""" +Given two graphs which are stitchable, stitchs the two graphs. +Assumes graphs have minimized node lables as well as that they +have the same number of qubits. This function is not optimized +for speed, so It is mainly used for testing purposes. + +Attributes: + asg_1 (AlgorithmSpecificGraph): first graph to be stitched + pauli_tracker_1 (PauliTracker): pauli tracker for first graph + asg_2 (AlgorithmSpecificGraph): second graph to be stitched + pauli_tracker_2 (PauliTracker): pauli tracker for second graph + +Returns: + asg_1 (AlgorithmSpecificGraph): first graph after stitching + pauli_tracker_1 (PauliTracker): pauli tracker for first graph after stitching +""" +function stitch_graphs(asg_1, pauli_tracker_1, asg_2, pauli_tracker_2) + if !( + asg_1.stitching_properties.gives_graph_output && + asg_2.stitching_properties.takes_graph_input + ) + error( + """Provided graphs don't have the correct types of inputs and outputs to be stitched. + Graph 1 gives graph output: $(asg_1.stitching_properties.gives_graph_output) + Graph 2 takes graph input: $(asg_2.stitching_properties.takes_graph_input) + """, + ) + end + if ( + length(asg_1.stitching_properties.graph_output_nodes) != + length(asg_2.stitching_properties.graph_input_nodes) + ) + error( + """Provided graphs don't have the correct numbers of inputs and outputs to be stitched. + Outputs: $(asg_1.stitching_properties.graph_output_nodes) + Inputs: $(asg_2.stitching_properties.graph_input_nodes) + """, + ) + end + + shift = asg_1.n_nodes + for neighborhood in asg_2.edge_data + push!(asg_1.edge_data, Set(neighborhood .+ shift)) + end + append!(asg_1.sqs, asg_2.sqs) + append!(asg_1.sqp, asg_2.sqp) + asg_1.n_nodes += asg_2.n_nodes + + for neighborhood in pauli_tracker_2.cond_paulis + push!( + pauli_tracker_1.cond_paulis, + [neighborhood[1] .+ shift, neighborhood[2] .+ shift], + ) + end + for layer in pauli_tracker_2.layering + push!(pauli_tracker_1.layering, layer .+ shift) + end + + append!(pauli_tracker_1.measurements, pauli_tracker_2.measurements) + pauli_tracker_1.n_nodes += pauli_tracker_2.n_nodes + + for index_of_inner_output_node = + 2:2:length(asg_1.stitching_properties.graph_output_nodes) + inner_output_node = + asg_1.stitching_properties.graph_output_nodes[index_of_inner_output_node] + outter_output_node = + asg_1.stitching_properties.graph_output_nodes[index_of_inner_output_node-1] + outter_input_node = + asg_2.stitching_properties.graph_input_nodes[index_of_inner_output_node] + shift + inner_input_node = + asg_2.stitching_properties.graph_input_nodes[index_of_inner_output_node-1] + shift + + # connect input node to output node + push!(asg_1.edge_data[outter_output_node], outter_input_node) + push!(asg_1.edge_data[outter_input_node], outter_output_node) + + pauli_tracker_1.cond_paulis[outter_input_node] = + [[inner_output_node], [outter_output_node]] + pauli_tracker_1.cond_paulis[inner_input_node] = [[outter_output_node], []] + end + + + asg_1.stitching_properties.gate_output_nodes = + asg_2.stitching_properties.gate_output_nodes .+ shift + asg_1.stitching_properties.graph_output_nodes = + asg_2.stitching_properties.graph_output_nodes .+ shift + + return asg_1, pauli_tracker_1 +end diff --git a/src/benchq/compilation/graph_states/ruby_slippers/graph_sim_data.jl b/src/benchq/compilation/graph_states/ruby_slippers/graph_sim_data.jl new file mode 100644 index 00000000..f30e767a --- /dev/null +++ b/src/benchq/compilation/graph_states/ruby_slippers/graph_sim_data.jl @@ -0,0 +1,285 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +#= +This contains the data required to run the graph simulation algorithm. +These tables are used to speed up the graph simulation algorithm by memoizing +the results of certain small calculations which are performed repeatedly. +=# + + +# Contains all the information required to implement a gate in the ICM format. +struct ICMOp + code::UInt8 + qubit1::Qubit + qubit2::Qubit + angle::Float64 + + ICMOp(code, qubit) = new(code, qubit, 0, 0) + ICMOp(code, qubit1, qubit2) = new(code, qubit1, qubit2, 0) + ICMOp(code, qubit1, qubit2, angle) = new(code, qubit1, qubit2, angle) +end +RZOp(qubit1, angle) = ICMOp(RZ_code, qubit1, 0, angle) + +"""Get qubit index of python operation""" +get_qubit_1(op) = pyconvert(Int, op.qubit_indices[0]) + 1 # +1 because Julia is 1-indexed +get_qubit_2(op) = pyconvert(Int, op.qubit_indices[1]) + 1 + +"""Get Python version of op_list of to speed up getting index""" +get_op_list() = pylist( + ["I", "S", "H", "N", "N", "N", "X", "Y", "Z", "CZ", "CNOT", "T", "T_Dagger", "RZ", "S_Dagger", "RX", "RY", "SX", "SX_Dagger"] +) + +"""Get index of operation name""" +get_op_index(op_list, op) = pyconvert(Int, op_list.index(op.gate.name)) + 1 + +pauli_op(index) = 1 <= index <= 4 # i.e. I, X, Y, Z +single_qubit_op(index) = 1 <= index <= 9 # Paulis, H, S, S_Dagger +double_qubit_op(index) = 10 <= index <= 11 # CZ, CNOT +non_clifford_op(index) = 12 <= index < 15 # T, T_Dagger, RX, RY, RZ +decompose_op(index) = index >= 15 # operations that must be decomposed to native gates + + +function convert_orquestra_op_to_icm_ops(op, supported_ops=get_op_list()) + op_index = get_op_index(supported_ops, op) + if single_qubit_op(op_index) + return [ICMOp(op_index, get_qubit_1(op))] + elseif double_qubit_op(op_index) + return [ICMOp(op_index, get_qubit_1(op), get_qubit_2(op))] + elseif non_clifford_op(op_index) + if op_index == RZ_code + return [RZOp(get_qubit_1(op), pyconvert(Float64, op.params[0]))] + else # T or T_Dagger + return [ICMOp(op_index, get_qubit_1(op))] + end + elseif decompose_op(op_index) + if op_index == 15 # S dagger + qubit = get_qubit_1(op) + return [ICMOp(Z_code, qubit), ICMOp(S_code, qubit)] + elseif op_index == 16 # RX + theta = pyconvert(Float64, op.params[0]) + return [ + ICMOp(H_code, get_qubit_1(op)), + RZOp(get_qubit_1(op), theta), + ICMOp(H_code, get_qubit_1(op)), + ] + elseif op_index == 17 # RY + theta = pyconvert(Float64, op.params[0]) + return [ + ICMOp(S_code, get_qubit_1(op)), + ICMOp(H_code, get_qubit_1(op)), + RZOp(get_qubit_1(op), theta), + ICMOp(H_code, get_qubit_1(op)), + ICMOp(S_code, get_qubit_1(op)), + ICMOp(Z_code, get_qubit_1(op)), + ] + elseif op_index == 18 # SX + return [ + ICMOp(H_code, get_qubit_1(op)), + ICMOp(S_code, get_qubit_1(op)), + ICMOp(H_code, get_qubit_1(op)), + ] + elseif op_index == 19 # SX_Dagger + return [ + ICMOp(H_code, get_qubit_1(op)), + ICMOp(S_code, get_qubit_1(op)), + ICMOp(Z_code, get_qubit_1(op)), + ICMOp(H_code, get_qubit_1(op)), + ] + end + else + error("Unsupported gate: $(op.code)") + end +end + +# numbers which correspond to each of the gates in multiply_sqs +const I_code = UInt8(1) +const S_code = UInt8(2) +const H_code = UInt8(3) +const SQRT_X_code = UInt8(4) +const HSH_code = UInt8(4) # e^{iπ/4} X HSH = SHS +const SH_code = UInt8(5) # Apply H first, then S +const HS_code = UInt8(6) # Apply S first, then H + +# Singe qubit Paulis +# external codes which must be distinct from the symplectic codes +const X_code = UInt8(7) +const Y_code = UInt8(8) +const Z_code = UInt8(9) + +# Internal codes for the paulis. Allows for faster manipulation and simplifies debugging. +const I_code_internal = UInt8(1) +const X_code_internal = UInt8(2) +const Y_code_internal = UInt8(3) +const Z_code_internal = UInt8(4) + +const external_to_internal_paulis = Dict( + I_code => I_code, X_code => X_code_internal, Y_code => Y_code_internal, Z_code => Z_code_internal +) + +# Two qubit gates +const CZ_code = UInt8(10) +const CNOT_code = UInt8(11) + +# Gates that get decomposed +const T_code = UInt8(12) +const T_Dagger_code = UInt8(13) +const RZ_code = UInt8(14) +const non_clifford_gate_codes = [T_code, T_Dagger_code, RZ_code] + +I_pauli_update = Dict(I_code => I_code, X_code_internal => X_code_internal, Y_code_internal => Y_code_internal, Z_code_internal => Z_code_internal) + +X_pauli_update = Dict(I_code => X_code_internal, X_code_internal => I_code, Y_code_internal => Z_code_internal, Z_code_internal => Y_code_internal) +Y_pauli_update = Dict(I_code => Y_code_internal, X_code_internal => Z_code_internal, Y_code_internal => I_code, Z_code_internal => X_code_internal) +Z_pauli_update = Dict(I_code => Z_code_internal, X_code_internal => Y_code_internal, Y_code_internal => X_code_internal, Z_code_internal => I_code) + +H_pauli_update = Dict(I_code => I_code, X_code_internal => Z_code_internal, Y_code_internal => Y_code_internal, Z_code_internal => X_code_internal) +S_pauli_update = Dict(I_code => I_code, X_code_internal => Y_code_internal, Y_code_internal => X_code_internal, Z_code_internal => Z_code_internal) +HS_pauli_update = Dict(I_code => I_code, X_code_internal => Z_code_internal, Y_code_internal => X_code_internal, Z_code_internal => Y_code_internal) +SH_pauli_update = Dict(I_code => I_code, X_code_internal => Y_code_internal, Y_code_internal => Z_code_internal, Z_code_internal => X_code_internal) +SQRT_X_pauli_update = Dict(I_code => I_code, X_code_internal => X_code_internal, Y_code_internal => Z_code_internal, Z_code_internal => Y_code_internal) + +pauli_mult_table = Dict(I_code => I_pauli_update, X_code_internal => X_pauli_update, Y_code_internal => Y_pauli_update, Z_code_internal => Z_pauli_update) +clifford_pauli_update = Dict(I_code => I_pauli_update, S_code => S_pauli_update, H_code => H_pauli_update, + SQRT_X_code => SQRT_X_pauli_update, SH_code => SH_pauli_update, HS_code => HS_pauli_update) + +#= +Lookup table for the product of two single qubit symplectic operations. +The index of the table corresponds to the first single qubit symplectic operation and the +value of the table corresponds to the second single qubit symplectic operation. The value +of the table is the single qubit symplectic operation that is the product of the two +single qubit symplectic operations. +=# +const multiply_sqs = UInt8[ + I_code S_code H_code SQRT_X_code SH_code HS_code + S_code I_code SH_code HS_code H_code SQRT_X_code + H_code HS_code I_code SH_code SQRT_X_code S_code + SQRT_X_code SH_code HS_code I_code S_code H_code + SH_code SQRT_X_code S_code H_code HS_code I_code + HS_code H_code SQRT_X_code S_code I_code SH_code +] + +#= +Tables for multiplying paulis and conjugating paulis by symplectic operations +=# +const multiply_sqp = [ + 1 2 3 4 + 2 1 4 3 + 3 4 1 2 + 4 3 2 1 +] + +#= +Product of two local clifford operations: + multiply_h & multiply_s store the results of multiplying h or s by the given value + multiply_by_* store the results of multiplying the value by s (sqrt_z) or sqrt_x + This is done by packing the row or column from the multiply_sqs table into a 32-bit + unsigned integer, where each nibble is one of the values (all shifted up by 4 to avoid + a shift at runtime. +=# + +# H has no excess paulis! +function multiply_h_from_left(asg, pauli_tracker, node) + # println("\nMultiplying h from left on qubit $(node)! the prepared graph state is:\n edge data $(asg.edge_data)\n symplectics $(asg.sqs)\n pauli $(asg.sqp)!") + asg.sqp[node] = H_pauli_update[asg.sqp[node]] + + asg.sqs[node] = multiply_sqs[H_code, asg.sqs[node]] + + track_conditional_paulis_through_h(pauli_tracker.cond_paulis, node) + # println("After multiplying h from left the prepared graph state is:\n edge data $(asg.edge_data)\n symplectics $(asg.sqs)\n pauli $(asg.sqp)!") +end + +excess_pauli_S_left = [I_code, Z_code_internal, I_code, X_code_internal, Z_code_internal, X_code_internal] +function multiply_s_from_left(asg, pauli_tracker, node) + conjugated_pauli = S_pauli_update[asg.sqp[node]] + excess_pauli = excess_pauli_S_left[asg.sqs[node]] + asg.sqp[node] = pauli_mult_table[conjugated_pauli][excess_pauli] + + asg.sqs[node] = multiply_sqs[S_code, asg.sqs[node]] + + track_conditional_paulis_through_s(pauli_tracker.cond_paulis, node) +end + + + +# conj_Z_from_right = [Z_code_internal, Z_code_internal, X_code_internal, Y_code_internal, Y_code_internal, X_code_internal] +# excess_pauli_S_right = [I_code, Z_code_internal, I_code, Z_code_internal, X_code_internal, X_code_internal] +excess_pauli_S_right = [Z_code_internal, I_code, X_code_internal, X_code_internal, Z_code_internal, I_code] +function multiply_s_dagger_from_right(asg, node) + # conjugated_pauli = conj_Z_from_right[asg.sqs[node]] + # excess_pauli = excess_pauli_S_right[asg.sqs[node]] + # total_added_pauli = pauli_mult_table[conjugated_pauli][excess_pauli] + # asg.sqp[node] = pauli_mult_table[asg.sqp[node]][total_added_pauli] + excess_pauli = excess_pauli_S_right[asg.sqs[node]] + asg.sqp[node] = pauli_mult_table[asg.sqp[node]][excess_pauli] + asg.sqs[node] = multiply_sqs[asg.sqs[node], S_code] + # print(" conjugated_pauli: ", conjugated_pauli, "\n") + # print(" excess_pauli: ", excess_pauli, "\n") + # print(" total_added_pauli: ", total_added_pauli, "\n") +end + +excess_pauli_SQRT_X_right = [I_code, X_code_internal, I_code, X_code_internal, Z_code_internal, Z_code_internal] +function multiply_sqrt_x_from_right(asg, node) + excess_pauli = excess_pauli_SQRT_X_right[asg.sqs[node]] + asg.sqp[node] = pauli_mult_table[asg.sqp[node]][excess_pauli] + asg.sqs[node] = multiply_sqs[asg.sqs[node], SQRT_X_code] +end + +#= +Table of states which result from applying CZ to all of the single qubit +Clifford gates acting on the basis states which are connected and disconnected +=# +const cz_table = [ + [ + (1, (I_code, I_code), (I_code, I_code)) (1, (Z_code_internal, I_code), (X_code_internal, I_code)) (1, (Z_code_internal, I_code), (Y_code_internal, I_code)) (1, (I_code, I_code), (Z_code_internal, I_code)) (1, (I_code, I_code), (I_code, S_code)) (1, (Z_code_internal, I_code), (X_code_internal, S_code)) (1, (Z_code_internal, I_code), (Y_code_internal, S_code)) (1, (I_code, I_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (I_code, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (I_code, H_code)) (1, (I_code, I_code), (I_code, I_code)) (1, (I_code, I_code), (I_code, I_code)) (1, (I_code, I_code), (Z_code_internal, I_code)) (1, (I_code, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (I_code, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (I_code, H_code)) (1, (I_code, I_code), (Z_code_internal, S_code)) (1, (I_code, I_code), (I_code, S_code)) (1, (I_code, I_code), (Z_code_internal, S_code)) (1, (I_code, I_code), (I_code, S_code)) + (1, (X_code_internal, I_code), (Z_code_internal, I_code)) (1, (Y_code_internal, I_code), (Y_code_internal, I_code)) (1, (Y_code_internal, I_code), (X_code_internal, I_code)) (1, (X_code_internal, I_code), (I_code, I_code)) (1, (X_code_internal, I_code), (Z_code_internal, S_code)) (1, (Y_code_internal, I_code), (Y_code_internal, S_code)) (1, (Y_code_internal, I_code), (X_code_internal, S_code)) (1, (X_code_internal, I_code), (I_code, S_code)) (0, (X_code_internal, I_code), (I_code, H_code)) (0, (Y_code_internal, I_code), (X_code_internal, H_code)) (0, (Y_code_internal, I_code), (X_code_internal, H_code)) (0, (X_code_internal, I_code), (I_code, H_code)) (1, (X_code_internal, I_code), (Z_code_internal, I_code)) (1, (X_code_internal, I_code), (Z_code_internal, I_code)) (1, (X_code_internal, I_code), (I_code, I_code)) (1, (X_code_internal, I_code), (I_code, I_code)) (0, (X_code_internal, I_code), (I_code, H_code)) (0, (Y_code_internal, I_code), (X_code_internal, H_code)) (0, (Y_code_internal, I_code), (X_code_internal, H_code)) (0, (X_code_internal, I_code), (I_code, H_code)) (1, (X_code_internal, I_code), (I_code, S_code)) (1, (X_code_internal, I_code), (Z_code_internal, S_code)) (1, (X_code_internal, I_code), (I_code, S_code)) (1, (X_code_internal, I_code), (Z_code_internal, S_code)) + (1, (Y_code_internal, I_code), (Z_code_internal, I_code)) (1, (X_code_internal, I_code), (Y_code_internal, I_code)) (1, (X_code_internal, I_code), (X_code_internal, I_code)) (1, (Y_code_internal, I_code), (I_code, I_code)) (1, (Y_code_internal, I_code), (Z_code_internal, S_code)) (1, (X_code_internal, I_code), (Y_code_internal, S_code)) (1, (X_code_internal, I_code), (X_code_internal, S_code)) (1, (Y_code_internal, I_code), (I_code, S_code)) (0, (Y_code_internal, I_code), (I_code, H_code)) (0, (X_code_internal, I_code), (X_code_internal, H_code)) (0, (X_code_internal, I_code), (X_code_internal, H_code)) (0, (Y_code_internal, I_code), (I_code, H_code)) (1, (Y_code_internal, I_code), (Z_code_internal, I_code)) (1, (X_code_internal, I_code), (Y_code_internal, I_code)) (1, (Y_code_internal, I_code), (I_code, I_code)) (1, (Y_code_internal, I_code), (I_code, I_code)) (0, (Y_code_internal, I_code), (I_code, H_code)) (0, (X_code_internal, I_code), (X_code_internal, H_code)) (0, (X_code_internal, I_code), (X_code_internal, H_code)) (0, (Y_code_internal, I_code), (I_code, H_code)) (1, (Y_code_internal, I_code), (I_code, S_code)) (1, (X_code_internal, I_code), (X_code_internal, S_code)) (1, (Y_code_internal, I_code), (I_code, S_code)) (1, (X_code_internal, I_code), (X_code_internal, S_code)) + (1, (Z_code_internal, I_code), (I_code, I_code)) (1, (I_code, I_code), (X_code_internal, I_code)) (1, (I_code, I_code), (Y_code_internal, I_code)) (1, (Z_code_internal, I_code), (Z_code_internal, I_code)) (1, (Z_code_internal, I_code), (I_code, S_code)) (1, (I_code, I_code), (X_code_internal, S_code)) (1, (I_code, I_code), (Y_code_internal, S_code)) (1, (Z_code_internal, I_code), (Z_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (1, (Z_code_internal, I_code), (I_code, I_code)) (1, (I_code, I_code), (X_code_internal, I_code)) (1, (I_code, I_code), (Y_code_internal, I_code)) (1, (I_code, I_code), (Y_code_internal, I_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (1, (I_code, I_code), (X_code_internal, S_code)) (1, (Z_code_internal, I_code), (I_code, S_code)) (1, (I_code, I_code), (X_code_internal, S_code)) (1, (Z_code_internal, I_code), (I_code, S_code)) + (1, (I_code, S_code), (I_code, I_code)) (1, (Z_code_internal, S_code), (X_code_internal, I_code)) (1, (Z_code_internal, S_code), (Y_code_internal, I_code)) (1, (I_code, S_code), (Z_code_internal, I_code)) (1, (I_code, S_code), (I_code, S_code)) (1, (Z_code_internal, S_code), (X_code_internal, S_code)) (1, (Z_code_internal, S_code), (Y_code_internal, S_code)) (1, (I_code, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, H_code)) (0, (Z_code_internal, S_code), (X_code_internal, H_code)) (0, (Z_code_internal, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (I_code, H_code)) (1, (I_code, S_code), (I_code, I_code)) (1, (I_code, S_code), (I_code, I_code)) (1, (I_code, S_code), (Z_code_internal, I_code)) (1, (I_code, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (I_code, H_code)) (0, (Z_code_internal, S_code), (X_code_internal, H_code)) (0, (Z_code_internal, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (I_code, H_code)) (1, (I_code, S_code), (Z_code_internal, S_code)) (1, (I_code, S_code), (I_code, S_code)) (1, (I_code, S_code), (Z_code_internal, S_code)) (1, (I_code, S_code), (I_code, S_code)) + (1, (X_code_internal, S_code), (Z_code_internal, I_code)) (1, (Y_code_internal, S_code), (Y_code_internal, I_code)) (1, (Y_code_internal, S_code), (X_code_internal, I_code)) (1, (X_code_internal, S_code), (I_code, I_code)) (1, (X_code_internal, S_code), (Z_code_internal, S_code)) (1, (Y_code_internal, S_code), (Y_code_internal, S_code)) (1, (Y_code_internal, S_code), (X_code_internal, S_code)) (1, (X_code_internal, S_code), (I_code, S_code)) (0, (X_code_internal, S_code), (I_code, H_code)) (0, (Y_code_internal, S_code), (X_code_internal, H_code)) (0, (Y_code_internal, S_code), (X_code_internal, H_code)) (0, (X_code_internal, S_code), (I_code, H_code)) (1, (X_code_internal, S_code), (Z_code_internal, I_code)) (1, (X_code_internal, S_code), (Z_code_internal, I_code)) (1, (X_code_internal, S_code), (I_code, I_code)) (1, (X_code_internal, S_code), (I_code, I_code)) (0, (X_code_internal, S_code), (I_code, H_code)) (0, (Y_code_internal, S_code), (X_code_internal, H_code)) (0, (Y_code_internal, S_code), (X_code_internal, H_code)) (0, (X_code_internal, S_code), (I_code, H_code)) (1, (X_code_internal, S_code), (I_code, S_code)) (1, (X_code_internal, S_code), (Z_code_internal, S_code)) (1, (X_code_internal, S_code), (I_code, S_code)) (1, (X_code_internal, S_code), (Z_code_internal, S_code)) + (1, (Y_code_internal, S_code), (Z_code_internal, I_code)) (1, (X_code_internal, S_code), (Y_code_internal, I_code)) (1, (X_code_internal, S_code), (X_code_internal, I_code)) (1, (Y_code_internal, S_code), (I_code, I_code)) (1, (Y_code_internal, S_code), (Z_code_internal, S_code)) (1, (X_code_internal, S_code), (Y_code_internal, S_code)) (1, (X_code_internal, S_code), (X_code_internal, S_code)) (1, (Y_code_internal, S_code), (I_code, S_code)) (0, (Y_code_internal, S_code), (I_code, H_code)) (0, (X_code_internal, S_code), (X_code_internal, H_code)) (0, (X_code_internal, S_code), (X_code_internal, H_code)) (0, (Y_code_internal, S_code), (I_code, H_code)) (1, (Y_code_internal, S_code), (Z_code_internal, I_code)) (1, (X_code_internal, S_code), (Y_code_internal, I_code)) (1, (Y_code_internal, S_code), (I_code, I_code)) (1, (Y_code_internal, S_code), (I_code, I_code)) (0, (Y_code_internal, S_code), (I_code, H_code)) (0, (X_code_internal, S_code), (X_code_internal, H_code)) (0, (X_code_internal, S_code), (X_code_internal, H_code)) (0, (Y_code_internal, S_code), (I_code, H_code)) (1, (Y_code_internal, S_code), (I_code, S_code)) (1, (X_code_internal, S_code), (X_code_internal, S_code)) (1, (Y_code_internal, S_code), (I_code, S_code)) (1, (X_code_internal, S_code), (X_code_internal, S_code)) + (1, (Z_code_internal, S_code), (I_code, I_code)) (1, (I_code, S_code), (X_code_internal, I_code)) (1, (I_code, S_code), (Y_code_internal, I_code)) (1, (Z_code_internal, S_code), (Z_code_internal, I_code)) (1, (Z_code_internal, S_code), (I_code, S_code)) (1, (I_code, S_code), (X_code_internal, S_code)) (1, (I_code, S_code), (Y_code_internal, S_code)) (1, (Z_code_internal, S_code), (Z_code_internal, S_code)) (0, (Z_code_internal, S_code), (I_code, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (Z_code_internal, S_code), (I_code, H_code)) (1, (Z_code_internal, S_code), (I_code, I_code)) (1, (I_code, S_code), (X_code_internal, I_code)) (1, (I_code, S_code), (Y_code_internal, I_code)) (1, (I_code, S_code), (Y_code_internal, I_code)) (0, (Z_code_internal, S_code), (I_code, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (Z_code_internal, S_code), (I_code, H_code)) (1, (I_code, S_code), (X_code_internal, S_code)) (1, (Z_code_internal, S_code), (I_code, S_code)) (1, (I_code, S_code), (X_code_internal, S_code)) (1, (Z_code_internal, S_code), (I_code, S_code)) + (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (X_code_internal, I_code)) (0, (I_code, H_code), (Y_code_internal, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (I_code, S_code)) (0, (I_code, H_code), (X_code_internal, S_code)) (0, (I_code, H_code), (Y_code_internal, S_code)) (0, (I_code, H_code), (Z_code_internal, S_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, S_code)) (0, (I_code, H_code), (I_code, S_code)) (0, (I_code, H_code), (Z_code_internal, S_code)) (0, (I_code, H_code), (I_code, S_code)) + (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (Y_code_internal, I_code)) (0, (X_code_internal, H_code), (X_code_internal, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (Z_code_internal, S_code)) (0, (X_code_internal, H_code), (Y_code_internal, S_code)) (0, (X_code_internal, H_code), (X_code_internal, S_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (Z_code_internal, S_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (X_code_internal, S_code)) + (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (Y_code_internal, I_code)) (0, (X_code_internal, H_code), (X_code_internal, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (Z_code_internal, S_code)) (0, (X_code_internal, H_code), (Y_code_internal, S_code)) (0, (X_code_internal, H_code), (X_code_internal, S_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (Z_code_internal, S_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (X_code_internal, S_code)) + (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (X_code_internal, I_code)) (0, (I_code, H_code), (Y_code_internal, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (I_code, S_code)) (0, (I_code, H_code), (X_code_internal, S_code)) (0, (I_code, H_code), (Y_code_internal, S_code)) (0, (I_code, H_code), (Z_code_internal, S_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, S_code)) (0, (I_code, H_code), (I_code, S_code)) (0, (I_code, H_code), (Z_code_internal, S_code)) (0, (I_code, H_code), (I_code, S_code)) + (1, (I_code, I_code), (I_code, I_code)) (1, (Z_code_internal, I_code), (X_code_internal, I_code)) (1, (Z_code_internal, I_code), (Y_code_internal, I_code)) (1, (I_code, I_code), (Z_code_internal, I_code)) (1, (I_code, I_code), (I_code, S_code)) (1, (Z_code_internal, I_code), (X_code_internal, S_code)) (1, (Z_code_internal, I_code), (Y_code_internal, S_code)) (1, (I_code, I_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (I_code, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (I_code, H_code)) (1, (I_code, I_code), (I_code, I_code)) (1, (I_code, I_code), (I_code, I_code)) (1, (X_code_internal, I_code), (I_code, I_code)) (1, (I_code, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (I_code, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (I_code, H_code)) (1, (I_code, I_code), (Z_code_internal, S_code)) (1, (I_code, I_code), (I_code, S_code)) (1, (X_code_internal, I_code), (I_code, S_code)) (1, (I_code, I_code), (I_code, S_code)) + (1, (I_code, I_code), (I_code, I_code)) (1, (Z_code_internal, I_code), (X_code_internal, I_code)) (1, (Y_code_internal, I_code), (X_code_internal, I_code)) (1, (X_code_internal, I_code), (I_code, I_code)) (1, (I_code, I_code), (I_code, S_code)) (1, (Z_code_internal, I_code), (X_code_internal, S_code)) (1, (Y_code_internal, I_code), (X_code_internal, S_code)) (1, (X_code_internal, I_code), (I_code, S_code)) (0, (I_code, I_code), (I_code, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (I_code, H_code)) (1, (I_code, I_code), (I_code, I_code)) (1, (I_code, I_code), (I_code, I_code)) (1, (I_code, I_code), (Z_code_internal, I_code)) (1, (X_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (I_code, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (I_code, H_code)) (1, (X_code_internal, I_code), (I_code, S_code)) (1, (I_code, I_code), (I_code, S_code)) (1, (I_code, I_code), (Z_code_internal, S_code)) (1, (I_code, I_code), (I_code, S_code)) + (1, (Z_code_internal, I_code), (I_code, I_code)) (1, (I_code, I_code), (X_code_internal, I_code)) (1, (I_code, I_code), (Y_code_internal, I_code)) (1, (Y_code_internal, I_code), (I_code, I_code)) (1, (Z_code_internal, I_code), (I_code, S_code)) (1, (I_code, I_code), (X_code_internal, S_code)) (1, (I_code, I_code), (Y_code_internal, S_code)) (1, (Y_code_internal, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (1, (Z_code_internal, I_code), (I_code, I_code)) (1, (I_code, I_code), (X_code_internal, I_code)) (1, (I_code, I_code), (Y_code_internal, I_code)) (1, (Y_code_internal, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (1, (I_code, I_code), (X_code_internal, S_code)) (1, (Z_code_internal, I_code), (I_code, S_code)) (1, (I_code, I_code), (X_code_internal, S_code)) (1, (Z_code_internal, I_code), (I_code, S_code)) + (1, (Z_code_internal, I_code), (I_code, I_code)) (1, (I_code, I_code), (X_code_internal, I_code)) (1, (I_code, I_code), (Y_code_internal, I_code)) (1, (Y_code_internal, I_code), (I_code, I_code)) (1, (Z_code_internal, I_code), (I_code, S_code)) (1, (I_code, I_code), (X_code_internal, S_code)) (1, (I_code, I_code), (Y_code_internal, S_code)) (1, (Y_code_internal, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (1, (Z_code_internal, I_code), (I_code, I_code)) (1, (I_code, I_code), (X_code_internal, I_code)) (1, (I_code, I_code), (Y_code_internal, I_code)) (1, (Y_code_internal, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (I_code, I_code), (X_code_internal, H_code)) (0, (Z_code_internal, I_code), (I_code, H_code)) (1, (I_code, I_code), (X_code_internal, S_code)) (1, (Z_code_internal, I_code), (I_code, S_code)) (1, (I_code, I_code), (X_code_internal, S_code)) (1, (Z_code_internal, I_code), (I_code, S_code)) + (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (X_code_internal, I_code)) (0, (I_code, H_code), (Y_code_internal, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (I_code, S_code)) (0, (I_code, H_code), (X_code_internal, S_code)) (0, (I_code, H_code), (Y_code_internal, S_code)) (0, (I_code, H_code), (Z_code_internal, S_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, S_code)) (0, (I_code, H_code), (I_code, S_code)) (0, (I_code, H_code), (Z_code_internal, S_code)) (0, (I_code, H_code), (I_code, S_code)) + (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (Y_code_internal, I_code)) (0, (X_code_internal, H_code), (X_code_internal, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (Z_code_internal, S_code)) (0, (X_code_internal, H_code), (Y_code_internal, S_code)) (0, (X_code_internal, H_code), (X_code_internal, S_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (Z_code_internal, S_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (X_code_internal, S_code)) + (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (Y_code_internal, I_code)) (0, (X_code_internal, H_code), (X_code_internal, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (Z_code_internal, S_code)) (0, (X_code_internal, H_code), (Y_code_internal, S_code)) (0, (X_code_internal, H_code), (X_code_internal, S_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (Z_code_internal, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (X_code_internal, H_code)) (0, (X_code_internal, H_code), (I_code, H_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (Z_code_internal, S_code)) (0, (X_code_internal, H_code), (I_code, S_code)) (0, (X_code_internal, H_code), (X_code_internal, S_code)) + (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (X_code_internal, I_code)) (0, (I_code, H_code), (Y_code_internal, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (I_code, S_code)) (0, (I_code, H_code), (X_code_internal, S_code)) (0, (I_code, H_code), (Y_code_internal, S_code)) (0, (I_code, H_code), (Z_code_internal, S_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (I_code, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (Z_code_internal, I_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (X_code_internal, H_code)) (0, (I_code, H_code), (I_code, H_code)) (0, (I_code, H_code), (X_code_internal, S_code)) (0, (I_code, H_code), (I_code, S_code)) (0, (I_code, H_code), (Z_code_internal, S_code)) (0, (I_code, H_code), (I_code, S_code)) + (1, (Z_code_internal, S_code), (I_code, I_code)) (1, (I_code, S_code), (X_code_internal, I_code)) (1, (I_code, S_code), (Y_code_internal, I_code)) (1, (X_code_internal, S_code), (I_code, I_code)) (1, (Z_code_internal, S_code), (I_code, S_code)) (1, (I_code, S_code), (X_code_internal, S_code)) (1, (I_code, S_code), (Y_code_internal, S_code)) (1, (X_code_internal, S_code), (I_code, S_code)) (0, (X_code_internal, S_code), (I_code, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (X_code_internal, S_code), (I_code, H_code)) (1, (I_code, S_code), (X_code_internal, I_code)) (1, (Z_code_internal, S_code), (I_code, I_code)) (1, (X_code_internal, S_code), (I_code, I_code)) (1, (X_code_internal, S_code), (I_code, I_code)) (0, (X_code_internal, S_code), (I_code, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (X_code_internal, S_code), (I_code, H_code)) (1, (I_code, S_code), (X_code_internal, S_code)) (1, (Z_code_internal, S_code), (I_code, S_code)) (1, (X_code_internal, S_code), (I_code, S_code)) (1, (Z_code_internal, S_code), (I_code, S_code)) + (1, (I_code, S_code), (I_code, I_code)) (1, (Z_code_internal, S_code), (X_code_internal, I_code)) (1, (X_code_internal, S_code), (X_code_internal, I_code)) (1, (I_code, S_code), (Z_code_internal, I_code)) (1, (I_code, S_code), (I_code, S_code)) (1, (Z_code_internal, S_code), (X_code_internal, S_code)) (1, (X_code_internal, S_code), (X_code_internal, S_code)) (1, (I_code, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, H_code)) (0, (Z_code_internal, S_code), (X_code_internal, H_code)) (0, (Z_code_internal, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (I_code, H_code)) (1, (I_code, S_code), (I_code, I_code)) (1, (I_code, S_code), (I_code, I_code)) (1, (I_code, S_code), (Z_code_internal, I_code)) (1, (I_code, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (I_code, H_code)) (0, (Z_code_internal, S_code), (X_code_internal, H_code)) (0, (Z_code_internal, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (I_code, H_code)) (1, (I_code, S_code), (Z_code_internal, S_code)) (1, (I_code, S_code), (I_code, S_code)) (1, (I_code, S_code), (Z_code_internal, S_code)) (1, (I_code, S_code), (I_code, S_code)) + (1, (Z_code_internal, S_code), (I_code, I_code)) (1, (I_code, S_code), (X_code_internal, I_code)) (1, (I_code, S_code), (Y_code_internal, I_code)) (1, (X_code_internal, S_code), (I_code, I_code)) (1, (Z_code_internal, S_code), (I_code, S_code)) (1, (I_code, S_code), (X_code_internal, S_code)) (1, (I_code, S_code), (Y_code_internal, S_code)) (1, (X_code_internal, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (I_code, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (Z_code_internal, S_code), (I_code, H_code)) (1, (Z_code_internal, S_code), (I_code, I_code)) (1, (I_code, S_code), (X_code_internal, I_code)) (1, (X_code_internal, S_code), (I_code, I_code)) (1, (X_code_internal, S_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (I_code, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (X_code_internal, H_code)) (0, (Z_code_internal, S_code), (I_code, H_code)) (1, (I_code, S_code), (X_code_internal, S_code)) (1, (Z_code_internal, S_code), (I_code, S_code)) (1, (X_code_internal, S_code), (I_code, S_code)) (1, (Z_code_internal, S_code), (I_code, S_code)) + (1, (I_code, S_code), (I_code, I_code)) (1, (Z_code_internal, S_code), (X_code_internal, I_code)) (1, (X_code_internal, S_code), (X_code_internal, I_code)) (1, (I_code, S_code), (Z_code_internal, I_code)) (1, (I_code, S_code), (I_code, S_code)) (1, (Z_code_internal, S_code), (X_code_internal, S_code)) (1, (X_code_internal, S_code), (X_code_internal, S_code)) (1, (I_code, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, H_code)) (0, (X_code_internal, S_code), (X_code_internal, H_code)) (0, (X_code_internal, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (I_code, H_code)) (1, (I_code, S_code), (I_code, I_code)) (1, (I_code, S_code), (I_code, I_code)) (1, (I_code, S_code), (Z_code_internal, I_code)) (1, (I_code, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (I_code, H_code)) (0, (X_code_internal, S_code), (X_code_internal, H_code)) (0, (X_code_internal, S_code), (X_code_internal, H_code)) (0, (I_code, S_code), (I_code, H_code)) (1, (I_code, S_code), (Z_code_internal, S_code)) (1, (I_code, S_code), (I_code, S_code)) (1, (I_code, S_code), (Z_code_internal, S_code)) (1, (I_code, S_code), (I_code, S_code)) + ], + [ + (0, (I_code, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (X_code_internal, I_code)) (0, (Z_code_internal, I_code), (Y_code_internal, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (Y_code_internal, S_code)) (0, (I_code, I_code), (Z_code_internal, S_code)) (1, (I_code, S_code), (I_code, SH_code)) (1, (I_code, I_code), (X_code_internal, H_code)) (1, (I_code, S_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (I_code, H_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (1, (I_code, I_code), (Z_code_internal, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (Y_code_internal, SH_code)) (1, (I_code, I_code), (I_code, SH_code)) (0, (Z_code_internal, S_code), (X_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (I_code, S_code), (Z_code_internal, S_code)) (0, (Z_code_internal, S_code), (I_code, S_code)) + (0, (X_code_internal, I_code), (Z_code_internal, I_code)) (0, (Y_code_internal, I_code), (Y_code_internal, I_code)) (0, (Y_code_internal, I_code), (X_code_internal, I_code)) (0, (X_code_internal, I_code), (I_code, I_code)) (0, (X_code_internal, I_code), (Z_code_internal, S_code)) (0, (Y_code_internal, I_code), (Y_code_internal, S_code)) (0, (Y_code_internal, I_code), (X_code_internal, S_code)) (0, (X_code_internal, I_code), (I_code, S_code)) (1, (X_code_internal, I_code), (I_code, H_code)) (1, (X_code_internal, S_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (X_code_internal, H_code)) (1, (X_code_internal, S_code), (I_code, SH_code)) (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (0, (Y_code_internal, S_code), (Z_code_internal, I_code)) (0, (Y_code_internal, S_code), (I_code, I_code)) (0, (X_code_internal, S_code), (I_code, I_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (1, (Y_code_internal, I_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (X_code_internal, SH_code)) (1, (Y_code_internal, I_code), (I_code, SH_code)) (0, (Y_code_internal, S_code), (I_code, S_code)) (0, (X_code_internal, S_code), (Z_code_internal, S_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (0, (Y_code_internal, S_code), (X_code_internal, S_code)) + (0, (Y_code_internal, I_code), (Z_code_internal, I_code)) (0, (X_code_internal, I_code), (Y_code_internal, I_code)) (0, (X_code_internal, I_code), (X_code_internal, I_code)) (0, (Y_code_internal, I_code), (I_code, I_code)) (0, (Y_code_internal, I_code), (Z_code_internal, S_code)) (0, (X_code_internal, I_code), (Y_code_internal, S_code)) (0, (X_code_internal, I_code), (X_code_internal, S_code)) (0, (Y_code_internal, I_code), (I_code, S_code)) (1, (X_code_internal, S_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (X_code_internal, H_code)) (1, (X_code_internal, S_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (I_code, H_code)) (0, (Y_code_internal, S_code), (Z_code_internal, I_code)) (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (0, (X_code_internal, S_code), (I_code, I_code)) (0, (Y_code_internal, S_code), (I_code, I_code)) (1, (Y_code_internal, I_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (Y_code_internal, SH_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (0, (Y_code_internal, S_code), (Z_code_internal, S_code)) (0, (Y_code_internal, S_code), (I_code, S_code)) (0, (X_code_internal, S_code), (X_code_internal, S_code)) + (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (X_code_internal, I_code)) (0, (I_code, I_code), (Y_code_internal, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (I_code, I_code), (Y_code_internal, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (1, (I_code, I_code), (I_code, H_code)) (1, (I_code, S_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (X_code_internal, H_code)) (1, (I_code, S_code), (I_code, SH_code)) (0, (Z_code_internal, S_code), (I_code, I_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) (1, (I_code, I_code), (I_code, SH_code)) (1, (I_code, I_code), (Y_code_internal, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (Z_code_internal, I_code), (I_code, SH_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (0, (Z_code_internal, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) + (0, (I_code, S_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (X_code_internal, I_code)) (0, (Z_code_internal, S_code), (Y_code_internal, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (X_code_internal, S_code)) (0, (Z_code_internal, S_code), (Y_code_internal, S_code)) (0, (I_code, S_code), (Z_code_internal, S_code)) (1, (I_code, I_code), (Z_code_internal, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (Y_code_internal, SH_code)) (1, (I_code, I_code), (I_code, SH_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (1, (I_code, I_code), (I_code, H_code)) (1, (I_code, S_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (X_code_internal, H_code)) (1, (I_code, S_code), (I_code, SH_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) + (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (0, (Y_code_internal, S_code), (Y_code_internal, I_code)) (0, (Y_code_internal, S_code), (X_code_internal, I_code)) (0, (X_code_internal, S_code), (I_code, I_code)) (0, (X_code_internal, S_code), (Z_code_internal, S_code)) (0, (Y_code_internal, S_code), (Y_code_internal, S_code)) (0, (Y_code_internal, S_code), (X_code_internal, S_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (1, (Y_code_internal, I_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (X_code_internal, SH_code)) (1, (Y_code_internal, I_code), (I_code, SH_code)) (0, (Y_code_internal, I_code), (Z_code_internal, I_code)) (0, (X_code_internal, I_code), (Z_code_internal, I_code)) (0, (X_code_internal, I_code), (I_code, I_code)) (0, (Y_code_internal, I_code), (I_code, I_code)) (1, (X_code_internal, S_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (X_code_internal, H_code)) (1, (X_code_internal, S_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (I_code, H_code)) (0, (X_code_internal, I_code), (I_code, S_code)) (0, (Y_code_internal, I_code), (Z_code_internal, S_code)) (0, (Y_code_internal, I_code), (I_code, S_code)) (0, (X_code_internal, I_code), (X_code_internal, S_code)) + (0, (Y_code_internal, S_code), (Z_code_internal, I_code)) (0, (X_code_internal, S_code), (Y_code_internal, I_code)) (0, (X_code_internal, S_code), (X_code_internal, I_code)) (0, (Y_code_internal, S_code), (I_code, I_code)) (0, (Y_code_internal, S_code), (Z_code_internal, S_code)) (0, (X_code_internal, S_code), (Y_code_internal, S_code)) (0, (X_code_internal, S_code), (X_code_internal, S_code)) (0, (Y_code_internal, S_code), (I_code, S_code)) (1, (Y_code_internal, I_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (Y_code_internal, SH_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (0, (X_code_internal, I_code), (Z_code_internal, I_code)) (0, (Y_code_internal, I_code), (Z_code_internal, I_code)) (0, (Y_code_internal, I_code), (I_code, I_code)) (0, (X_code_internal, I_code), (I_code, I_code)) (1, (X_code_internal, I_code), (I_code, H_code)) (1, (X_code_internal, S_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (X_code_internal, H_code)) (1, (X_code_internal, S_code), (I_code, SH_code)) (0, (Y_code_internal, I_code), (I_code, S_code)) (0, (X_code_internal, I_code), (Z_code_internal, S_code)) (0, (X_code_internal, I_code), (I_code, S_code)) (0, (Y_code_internal, I_code), (X_code_internal, S_code)) + (0, (Z_code_internal, S_code), (I_code, I_code)) (0, (I_code, S_code), (X_code_internal, I_code)) (0, (I_code, S_code), (Y_code_internal, I_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) (0, (Z_code_internal, S_code), (I_code, S_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (0, (I_code, S_code), (Y_code_internal, S_code)) (0, (Z_code_internal, S_code), (Z_code_internal, S_code)) (1, (I_code, I_code), (I_code, SH_code)) (1, (I_code, I_code), (Y_code_internal, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (Z_code_internal, I_code), (I_code, SH_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (1, (I_code, S_code), (I_code, SH_code)) (1, (I_code, I_code), (X_code_internal, H_code)) (1, (I_code, S_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (I_code, H_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (I_code, I_code), (Z_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) + (1, (I_code, SH_code), (I_code, S_code)) (1, (I_code, H_code), (X_code_internal, I_code)) (1, (I_code, SH_code), (X_code_internal, S_code)) (1, (I_code, H_code), (I_code, I_code)) (1, (I_code, H_code), (Z_code_internal, S_code)) (1, (I_code, H_code), (X_code_internal, S_code)) (1, (I_code, H_code), (Y_code_internal, S_code)) (1, (I_code, H_code), (I_code, S_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (X_code_internal, S_code), (X_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (I_code, S_code), (Z_code_internal, S_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (I_code, I_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) + (1, (X_code_internal, H_code), (I_code, I_code)) (1, (X_code_internal, SH_code), (X_code_internal, S_code)) (1, (X_code_internal, H_code), (X_code_internal, I_code)) (1, (X_code_internal, SH_code), (I_code, S_code)) (1, (X_code_internal, H_code), (I_code, S_code)) (1, (Y_code_internal, H_code), (X_code_internal, S_code)) (1, (X_code_internal, H_code), (X_code_internal, S_code)) (1, (Y_code_internal, H_code), (I_code, S_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (Z_code_internal, S_code)) (0, (Z_code_internal, S_code), (I_code, S_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (0, (I_code, I_code), (Z_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (X_code_internal, S_code), (I_code, I_code)) + (1, (X_code_internal, SH_code), (I_code, S_code)) (1, (X_code_internal, H_code), (X_code_internal, I_code)) (1, (X_code_internal, SH_code), (X_code_internal, S_code)) (1, (X_code_internal, H_code), (I_code, I_code)) (1, (Y_code_internal, H_code), (I_code, S_code)) (1, (X_code_internal, H_code), (X_code_internal, S_code)) (1, (X_code_internal, H_code), (Y_code_internal, S_code)) (1, (X_code_internal, H_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (I_code, S_code)) (0, (I_code, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (0, (X_code_internal, S_code), (I_code, I_code)) (0, (I_code, S_code), (I_code, I_code)) + (1, (I_code, H_code), (I_code, I_code)) (1, (I_code, SH_code), (X_code_internal, S_code)) (1, (I_code, H_code), (X_code_internal, I_code)) (1, (I_code, SH_code), (I_code, S_code)) (1, (I_code, H_code), (I_code, S_code)) (1, (I_code, H_code), (Y_code_internal, S_code)) (1, (I_code, H_code), (X_code_internal, S_code)) (1, (Z_code_internal, H_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (0, (X_code_internal, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (0, (Z_code_internal, S_code), (I_code, I_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) + (0, (I_code, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (Y_code_internal, S_code)) (0, (I_code, I_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (Y_code_internal, I_code)) (0, (Z_code_internal, I_code), (X_code_internal, I_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (X_code_internal, S_code), (X_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (I_code, S_code), (Z_code_internal, S_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (1, (I_code, I_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (Z_code_internal, SH_code)) (0, (X_code_internal, S_code), (I_code, I_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (1, (I_code, I_code), (X_code_internal, H_code)) (1, (I_code, S_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, H_code)) (1, (I_code, S_code), (X_code_internal, SH_code)) + (0, (I_code, I_code), (Z_code_internal, S_code)) (0, (Z_code_internal, I_code), (Y_code_internal, S_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (X_code_internal, I_code)) (0, (Z_code_internal, I_code), (Y_code_internal, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (Z_code_internal, S_code)) (0, (Z_code_internal, S_code), (I_code, S_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (Z_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) (0, (Z_code_internal, S_code), (I_code, I_code)) (0, (I_code, S_code), (I_code, I_code)) (1, (I_code, S_code), (I_code, SH_code)) (1, (I_code, I_code), (X_code_internal, H_code)) (1, (I_code, S_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (I_code, H_code)) + (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (Y_code_internal, S_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (X_code_internal, I_code)) (0, (I_code, I_code), (Y_code_internal, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, S_code), (I_code, S_code)) (0, (I_code, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (X_code_internal, S_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, SH_code)) (1, (I_code, I_code), (Z_code_internal, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (I_code, I_code)) (1, (I_code, I_code), (I_code, H_code)) (1, (X_code_internal, S_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (I_code, H_code)) (1, (I_code, S_code), (I_code, SH_code)) + (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (I_code, I_code), (Y_code_internal, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (Y_code_internal, I_code)) (0, (I_code, I_code), (X_code_internal, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (0, (X_code_internal, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (1, (Z_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, SH_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (X_code_internal, S_code), (I_code, I_code)) (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (1, (X_code_internal, S_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, H_code)) (1, (I_code, S_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (I_code, H_code)) + (1, (I_code, H_code), (Z_code_internal, S_code)) (1, (I_code, H_code), (X_code_internal, S_code)) (1, (I_code, H_code), (Y_code_internal, S_code)) (1, (I_code, H_code), (I_code, S_code)) (1, (I_code, H_code), (I_code, I_code)) (1, (I_code, SH_code), (X_code_internal, S_code)) (1, (I_code, H_code), (X_code_internal, I_code)) (1, (I_code, SH_code), (I_code, S_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (X_code_internal, S_code)) (0, (Z_code_internal, S_code), (I_code, S_code)) (0, (I_code, S_code), (Z_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) + (1, (X_code_internal, H_code), (I_code, S_code)) (1, (Y_code_internal, H_code), (X_code_internal, S_code)) (1, (X_code_internal, H_code), (X_code_internal, S_code)) (1, (Y_code_internal, H_code), (I_code, S_code)) (1, (X_code_internal, SH_code), (I_code, S_code)) (1, (X_code_internal, H_code), (X_code_internal, I_code)) (1, (X_code_internal, SH_code), (X_code_internal, S_code)) (1, (X_code_internal, H_code), (I_code, I_code)) (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (X_code_internal, S_code), (I_code, I_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (X_code_internal, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) + (1, (Y_code_internal, H_code), (I_code, S_code)) (1, (X_code_internal, H_code), (X_code_internal, S_code)) (1, (X_code_internal, H_code), (Y_code_internal, S_code)) (1, (X_code_internal, H_code), (I_code, S_code)) (1, (X_code_internal, H_code), (I_code, I_code)) (1, (X_code_internal, SH_code), (X_code_internal, S_code)) (1, (X_code_internal, H_code), (X_code_internal, I_code)) (1, (X_code_internal, SH_code), (I_code, S_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (0, (X_code_internal, S_code), (I_code, I_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (I_code, I_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (I_code, S_code), (Z_code_internal, S_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (0, (X_code_internal, S_code), (X_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (I_code, I_code)) + (1, (I_code, H_code), (I_code, S_code)) (1, (I_code, H_code), (Y_code_internal, S_code)) (1, (I_code, H_code), (X_code_internal, S_code)) (1, (Z_code_internal, H_code), (I_code, S_code)) (1, (I_code, SH_code), (I_code, S_code)) (1, (I_code, H_code), (X_code_internal, I_code)) (1, (I_code, SH_code), (X_code_internal, S_code)) (1, (I_code, H_code), (I_code, I_code)) (0, (Z_code_internal, S_code), (I_code, I_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (I_code, I_code), (Z_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (I_code, S_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) + (0, (X_code_internal, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (Y_code_internal, S_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (0, (X_code_internal, S_code), (I_code, S_code)) (0, (X_code_internal, S_code), (I_code, I_code)) (0, (I_code, S_code), (X_code_internal, I_code)) (0, (I_code, S_code), (Y_code_internal, I_code)) (0, (X_code_internal, S_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (I_code, I_code), (Z_code_internal, S_code)) (1, (I_code, I_code), (X_code_internal, H_code)) (1, (I_code, S_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, H_code)) (1, (I_code, S_code), (X_code_internal, SH_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (I_code, I_code)) (1, (I_code, I_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (Z_code_internal, SH_code)) + (0, (I_code, S_code), (I_code, S_code)) (0, (Z_code_internal, S_code), (X_code_internal, S_code)) (0, (Z_code_internal, S_code), (Y_code_internal, S_code)) (0, (I_code, S_code), (Z_code_internal, S_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (Z_code_internal, S_code), (Y_code_internal, I_code)) (0, (Z_code_internal, S_code), (X_code_internal, I_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (I_code, I_code), (Z_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (X_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (1, (I_code, S_code), (I_code, SH_code)) (1, (I_code, I_code), (X_code_internal, H_code)) (1, (I_code, S_code), (X_code_internal, SH_code)) (1, (I_code, I_code), (I_code, H_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (Z_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) + (0, (Z_code_internal, S_code), (I_code, S_code)) (0, (I_code, S_code), (X_code_internal, S_code)) (0, (I_code, S_code), (Y_code_internal, S_code)) (0, (Z_code_internal, S_code), (Z_code_internal, S_code)) (0, (Z_code_internal, S_code), (Z_code_internal, I_code)) (0, (I_code, S_code), (Y_code_internal, I_code)) (0, (I_code, S_code), (X_code_internal, I_code)) (0, (Z_code_internal, S_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (1, (I_code, I_code), (I_code, H_code)) (1, (X_code_internal, S_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (I_code, H_code)) (1, (I_code, S_code), (I_code, SH_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, SH_code)) (1, (I_code, I_code), (Z_code_internal, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) + (0, (I_code, S_code), (Z_code_internal, S_code)) (0, (X_code_internal, S_code), (Y_code_internal, S_code)) (0, (X_code_internal, S_code), (X_code_internal, S_code)) (0, (I_code, S_code), (I_code, S_code)) (0, (I_code, S_code), (I_code, I_code)) (0, (X_code_internal, S_code), (X_code_internal, I_code)) (0, (X_code_internal, S_code), (Y_code_internal, I_code)) (0, (I_code, S_code), (Z_code_internal, I_code)) (0, (Z_code_internal, I_code), (I_code, S_code)) (0, (I_code, I_code), (X_code_internal, S_code)) (0, (I_code, I_code), (I_code, S_code)) (0, (Z_code_internal, I_code), (Z_code_internal, S_code)) (1, (X_code_internal, S_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, H_code)) (1, (I_code, S_code), (I_code, SH_code)) (1, (X_code_internal, I_code), (I_code, H_code)) (0, (Z_code_internal, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (Z_code_internal, I_code)) (0, (I_code, I_code), (I_code, I_code)) (0, (Z_code_internal, I_code), (I_code, I_code)) (1, (Z_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (X_code_internal, SH_code)) (1, (X_code_internal, I_code), (I_code, SH_code)) (1, (I_code, I_code), (I_code, SH_code)) + ] +] diff --git a/src/benchq/compilation/graph_states/ruby_slippers/ruby_slippers.jl b/src/benchq/compilation/graph_states/ruby_slippers/ruby_slippers.jl new file mode 100644 index 00000000..cbd402cd --- /dev/null +++ b/src/benchq/compilation/graph_states/ruby_slippers/ruby_slippers.jl @@ -0,0 +1,624 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +#= +This module contains functions for getting the graph state corresponding to a +state generated by a circuit using a graph state simulator (graph_sim) from the paper +"Fast simulation of stabilizer circuits using a graph state representation" by Simon +Anders, Hans J. Briegel. https://arxiv.org/abs/quant-ph/0504117". We have modified +the algorithm to ignore paulis. +=# + +using PythonCall +using StatsBase + +const Qubit = UInt32 +const AdjList = Set{Qubit} +const erase_line = " \b\b\b\b\b\b\b\b" + +include("verbose_iterator.jl") +include("graph_sim_data.jl") +include("../pauli_tracker/pauli_tracker.jl") +include("algorithm_specific_graph.jl") +include("asg_stitching.jl") +include("../substrate_scheduler/substrate_scheduler.jl") + +""" +Converts a given circuit in Clifford + T form to icm form and simulates the icm +circuit using the graph sim mini simulator. Returns the adjacency list of the graph +state created by the icm circuit along with the single qubit operations on each vertex. +teleportation_threshold, min_neighbor_degree, teleportation_distance, and max_num_neighbors_to_search +are metaparameters which can be optimized to speed up the simulation. This function +serves as the primary entry point for the Ruby Slippers algorithm via pythoncall. + +Args: + orquestra_circuit::Circuit Circuit to be simulated + verbose::Bool Whether to print progress + takes_graph_input::Bool Whether the circuit takes a graph state as input and thus + can be stitched to a previous graph state. + gives_graph_output::Bool Whether the circuit gives a graph state as output and thus + can be stitched to a future graph state. + optimization::String Which layering optimization to use in the pauli tracker. + Options are "Time", "Space", "Variable" + max_num_qubits::Int How many gates to put in each layer in the case of "Variable" + optimal_dag_density::Int How dense to make the dag. Higher values require more time, + but can be more optimizable. Ranges from 0-infinity. + use_fully_optimized_dag::Bool Whether to use the fully optimized dag, is more efficient + than setting the optimal_dag_density to a high value. + teleportation_threshold::Int Max node degree allowed before state is teleported + teleportation_distance::Int Number of teleportations to do when state is teleported + min_neighbor_degree::Int stop searching for neighbor with low degree if + neighbor has at least this many neighbors + max_num_neighbors_to_search::Int Max number of neighbors to search through when finding + a neighbor with low degree + decomposition_strategy::Int Strategy for decomposing non-clifford gate + 0: keep current qubit as data qubit + 1: teleport data to new qubit which becomes data qubit + max_graph_size::Int Maximum number of nodes in the graph state + max_time::Float64 Maximum time to spend compiling the circuit + + +Returns: + python_compiled_data::Dict Data describing the compiled circuit + proportion::Float64 Proportion of the circuit that was compiled +""" +function run_ruby_slippers( + orquestra_circuit; + verbose::Bool=true, + takes_graph_input::Bool=true, + gives_graph_output::Bool=true, + optimization::String="Space", + max_num_qubits::Int64=1, + optimal_dag_density::Int=1, + use_fully_optimized_dag::Bool=false, + teleportation_threshold::Int64=40, + teleportation_distance::Int64=4, + min_neighbor_degree::Int64=6, + max_num_neighbors_to_search::Int64=100000, + decomposition_strategy::Int64=0, + max_time::Float64=1e8, + max_graph_size=nothing, +) + if decomposition_strategy == 1 + error("Decomposition strategy 1 is not yet supported") + end + # params which can be optimized to speed up computation + hyperparams = RbSHyperparams( + teleportation_threshold, + teleportation_distance, + min_neighbor_degree, + max_num_neighbors_to_search, + decomposition_strategy, + ) + + if max_graph_size === nothing + max_graph_size = get_max_n_nodes( + orquestra_circuit, + hyperparams.teleportation_distance, + takes_graph_input, + gives_graph_output, + ) + else + max_graph_size = pyconvert(UInt32, max_graph_size) + end + + if verbose + (asg, pauli_tracker, proportion) = + @time get_rbs_graph_state_data( + orquestra_circuit; + verbose=verbose, + takes_graph_input=takes_graph_input, + gives_graph_output=gives_graph_output, + optimization=optimization, + max_num_qubits=max_num_qubits, + optimal_dag_density=optimal_dag_density, + use_fully_optimized_dag=use_fully_optimized_dag, + hyperparams=hyperparams, + max_graph_size=max_graph_size, + max_time=max_time, + ) + else + (asg, pauli_tracker, proportion) = + get_rbs_graph_state_data( + orquestra_circuit; + verbose=verbose, + takes_graph_input=takes_graph_input, + gives_graph_output=gives_graph_output, + optimization=optimization, + max_num_qubits=max_num_qubits, + hyperparams=hyperparams, + max_graph_size=max_graph_size, + max_time=max_time, + ) + end + + if proportion == 1.0 + num_logical_qubits = get_num_logical_qubits(pauli_tracker.layering, asg, optimization, verbose) + num_layers = length(pauli_tracker.layering) + (graph_creation_tocks_per_layer, t_states_per_layer, rotations_per_layer) = + two_row_scheduler(asg, pauli_tracker, num_logical_qubits, optimization, verbose) + python_compiled_data = Dict( + "num_logical_qubits" => num_logical_qubits, + "num_layers" => num_layers, + "graph_creation_tocks_per_layer" => pylist(graph_creation_tocks_per_layer), + "t_states_per_layer" => pylist(t_states_per_layer), + "rotations_per_layer" => pylist(rotations_per_layer), + ) + return python_compiled_data, proportion + else + # if we did not finish compiling the circuit, return the proportion of the circuit + return 0, proportion + end +end + +""" +Get the maximum number of nodes that the graph could possibly need. Helps to reduce +memory usage when creating the graph state and the pauli tracker. Tends to be a +massive overestimate, but is better than running out of memory. +""" +function get_max_n_nodes( + orquestra_circuit, + teleportation_distance, + takes_graph_input, + gives_graph_output, +) + n_qubits = pyconvert(Int, orquestra_circuit.n_qubits) + supported_ops = get_op_list() + + n_magic_state_injection_teleports = 0 + n_ruby_slippers_teleports = 0 + + for op in orquestra_circuit.operations + if occursin("ResetOperation", pyconvert(String, op.__str__())) + n_magic_state_injection_teleports += 1 + continue + else + op_index = get_op_index(supported_ops, op) + if double_qubit_op(op_index) + n_ruby_slippers_teleports += 2 + elseif non_clifford_op(op_index) + n_magic_state_injection_teleports += 1 + n_ruby_slippers_teleports += 1 + end + end + end + + n_projected_nodes = n_magic_state_injection_teleports + + n_ruby_slippers_teleports * teleportation_distance + + n_qubits + + if takes_graph_input + n_projected_nodes += BUFFER_SIZE * n_qubits + end + if gives_graph_output + n_projected_nodes += 4 * n_qubits + end + + return convert(UInt32, n_projected_nodes) +end + +""" +Get the vertices of a graph state corresponding to enacting the given circuit +on the |0> state. Also gives the single qubit clifford operation on each node. + +Args: + orquestra_circuit::Circuit Circuit to be simulated + verbose::Bool Whether to print progress + takes_graph_input::Bool Whether the circuit takes a graph state as input and thus + can be stitched to a previous graph state. + gives_graph_output::Bool Whether the circuit gives a graph state as output and thus + can be stitched to a future graph state. + optimization::String Which layering optimization to use in the pauli tracker. + Options are "Time", "Space", "Variable" + max_num_qubits::Int How many gates to put in each layer in the case of "Variable" + optimal_dag_density::Int How dense to make the dag. Higher values require more time, + but can be more optimizable. Ranges from 0-infinity. + use_fully_optimized_dag::Bool Whether to use the fully optimized dag, is more efficient + than setting the optimal_dag_density to a high value. + hyperparams::RbSHyperparams Metaparameters which can be optimized to speed up the + compilation. + max_graph_size::UInt32 Maximum number of nodes in the graph state + max_time::Float64 Maximum time to spend compiling the circuit + +Raises: + ValueError: if an unsupported gate is encountered + +Returns: + Vector{UInt8}: the list of single qubit clifford operations on each node + Vector{AdjList}: the adjacency list describing the graph corresponding to the graph state +""" +function get_rbs_graph_state_data( + orquestra_circuit; + verbose::Bool=true, + takes_graph_input::Bool=true, + gives_graph_output::Bool=true, + manually_stitchable::Bool=false, + optimization::String="Space", + max_num_qubits::Int64=1, + optimal_dag_density::Int=1, + use_fully_optimized_dag::Bool=false, + hyperparams::RbSHyperparams=default_hyperparams, + max_graph_size::UInt32=UInt32(100000), + max_time::Float64=1e8, +) + if hyperparams.decomposition_strategy == 1 + error("Decomposition strategy 1 is not yet supported") + end + + n_qubits = pyconvert(Int, orquestra_circuit.n_qubits) + + verbose && println("Allocating memory for ASG and Pauli Tracker...") + if takes_graph_input + asg, pauli_tracker = initialize_for_graph_input(max_graph_size, n_qubits, optimization, max_num_qubits, optimal_dag_density, use_fully_optimized_dag) + else + asg = AlgorithmSpecificGraphAllZero(max_graph_size, n_qubits) + pauli_tracker = PauliTracker(n_qubits, optimization, max_num_qubits, optimal_dag_density, use_fully_optimized_dag) + end + + total_length = length(orquestra_circuit.operations) + counter = 0 + start_time = time() + + for (counter, orquestra_op) in enumerate( + VerboseIterator( + orquestra_circuit.operations, + verbose, + "Compiling graph state using Ruby Slippers...", + true, + ) + ) + elapsed_time = time() - start_time + # End early if we have exceeded the max time + if elapsed_time >= max_time + delete_excess_asg_space!(asg) + percent = counter / total_length + return asg, pauli_tracker, percent + end + + # Apply current operation + if occursin("ResetOperation", pyconvert(String, orquestra_op.__str__())) # reset operation + asg.n_nodes += 1 + asg.stitching_properties.gate_output_nodes[get_qubit_1(orquestra_op)] = asg.n_nodes + add_new_qubit_to_pauli_tracker!(pauli_tracker) + continue + else + icm_ops = convert_orquestra_op_to_icm_ops(orquestra_op) + for op in icm_ops + if op.code in non_clifford_gate_codes + apply_non_clifford_gate!(asg, pauli_tracker, op, hyperparams) + elseif op.code in [I_code, X_code, Y_code, Z_code, H_code, S_code] # single qubit clifford gates + op_code = op.code + node = asg.stitching_properties.gate_output_nodes[op.qubit1] # node this operation with act on + if op_code in [I_code, X_code, Y_code, Z_code] + asg.sqp[node] = multiply_sqp[asg.sqp[node], external_to_internal_paulis[op_code]] + elseif op_code == H_code + multiply_h_from_left(asg, pauli_tracker, node) + elseif op_code == S_code + multiply_s_from_left(asg, pauli_tracker, node) + end + elseif op.code in [CZ_code, CNOT_code] # two qubit clifford gates + op_code = op.code + node_1 = asg.stitching_properties.gate_output_nodes[op.qubit1] + node_2 = asg.stitching_properties.gate_output_nodes[op.qubit2] + if op_code == CNOT_code + # CNOT = (I ⊗ H) CZ (I ⊗ H) + multiply_h_from_left(asg, pauli_tracker, node_2) + cz(asg, node_1, node_2, pauli_tracker, hyperparams) + # update node_2 to the new qubit if previous cz teleported it + node_2 = asg.stitching_properties.gate_output_nodes[op.qubit2] + multiply_h_from_left(asg, pauli_tracker, node_2) + elseif op_code == CZ_code + cz(asg, node_1, node_2, pauli_tracker, hyperparams) + end + else + error("Unsupported gate: $(op.code)") + end + end + end + end + + # add teleportations at end so we can connect to next buffer + nodes_to_remove = Set{Qubit}([]) + if gives_graph_output + add_output_nodes!(asg, pauli_tracker, nodes_to_remove) + end + if takes_graph_input + prune_buffer!(asg, pauli_tracker, n_qubits, nodes_to_remove) + end + + calculate_layering!(pauli_tracker, asg, nodes_to_remove, verbose) + delete_excess_asg_space!(asg) + + if manually_stitchable + verbose && println("Minimizing node labels for manual stitching...") + asg, pauli_tracker = minimize_node_labels!(asg, pauli_tracker, nodes_to_remove) + end + + return asg, pauli_tracker, 1.0 +end + +""" +Implement non-clifford gates via gate teleportation as described in +https://arxiv.org/abs/1509.02004. This is commonly reffered to as the ICM +format. +""" +function apply_non_clifford_gate!(asg, pauli_tracker, op, hyperparams) + original_qubit = op.qubit1 # qubit the T gate was originally acting on before ICM + asg.n_nodes += 1 + # println(compiled_qubit, " -> ", asg.n_nodes, " ") + # TODO: implement different decomposition_strategies with new tracker + original_node = Qubit(asg.stitching_properties.gate_output_nodes[original_qubit]) + compiled_node = Qubit(asg.n_nodes) + # add new qubit to be tracked + add_new_qubit_to_pauli_tracker!(pauli_tracker) + # apply CX + multiply_h_from_left(asg, pauli_tracker, compiled_node) + cz_no_teleport(asg, original_node, compiled_node, pauli_tracker, hyperparams) + # update original_node to the new qubit if that cz teleported it + original_node = Qubit(asg.stitching_properties.gate_output_nodes[original_qubit]) + multiply_h_from_left(asg, pauli_tracker, compiled_node) + # mark compiled qubit as where the data is being stored + if hyperparams.decomposition_strategy == 0 + asg.stitching_properties.gate_output_nodes[original_qubit] = compiled_node + end + # Update pauli Tracker + add_z_to_pauli_tracker!(pauli_tracker.cond_paulis, original_node, compiled_node) + if op.code == RZ_code + add_measurement!(pauli_tracker.measurements, op.code, original_node, op.angle) + else + add_measurement!(pauli_tracker.measurements, op.code, original_node) + end +end + +""" +Delete excess parts of the ASG to save space once we have completed +the computation. This is done by resizing the vectors to only contain +the nodes which are actually used in the graph state. +""" +function delete_excess_asg_space!(asg) + resize!(asg.edge_data, asg.n_nodes) + resize!(asg.sqs, asg.n_nodes) + resize!(asg.sqp, asg.n_nodes) +end + +""" +Check if a vertex is almost isolated. A vertex is almost isolated if it has no +neighbors or if it has one neighbor and that neighbor is the given vertex. + +Args: + set::AdjList set of neighbors of a vertex + vertex::Int vertex to check if it is almost isolated + +Returns: + Bool: whether the vertex is almost isolated +""" +function check_almost_isolated(set, vertex) + len = length(set) + return (len == 0) || (len == 1 && vertex in set) +end + +""" +Apply a CZ gate to the graph on the given vertices. + +Args: + sqs::Vector{UInt8} single qubit clifford operation on each node + adj::Vector{AdjList} adjacency list describing the graph state + vertex_1::Int vertex to enact the CZ gate on + vertex_2::Int vertex to enact the CZ gate on +""" +function cz(asg, vertex_1, vertex_2, pauli_tracker, hyperparams) + if length(asg.edge_data[vertex_1]) >= hyperparams.teleportation_threshold + distance = hyperparams.teleportation_distance + vertex_1 = teleportation!(asg, vertex_1, pauli_tracker, hyperparams, distance) + end + if length(asg.edge_data[vertex_2]) >= hyperparams.teleportation_threshold + distance = hyperparams.teleportation_distance + vertex_2 = teleportation!(asg, vertex_2, pauli_tracker, hyperparams, distance) + end + + cz_no_teleport(asg, vertex_1, vertex_2, pauli_tracker, hyperparams) +end + +function cz_no_teleport(asg, vertex_1, vertex_2, pauli_tracker, hyperparams) + adj1, adj2 = asg.edge_data[vertex_1], asg.edge_data[vertex_2] + + if !check_almost_isolated(adj1, vertex_2) + remove_sqs!(asg, vertex_1, vertex_2, hyperparams) + end + if !check_almost_isolated(adj2, vertex_1) + remove_sqs!(asg, vertex_2, vertex_1, hyperparams) + end + if !check_almost_isolated(adj1, vertex_2) + remove_sqs!(asg, vertex_1, vertex_2, hyperparams) + end + + # Now that the verticies CZ is acting on are either isolated or have sqs = I or S, + # apply a CZ gate between those two gates. Only requires using lookup table. + track_conditional_paulis_through_cz(pauli_tracker.cond_paulis, vertex_1, vertex_2) + + connected = vertex_1 in asg.edge_data[vertex_2] || vertex_2 in asg.edge_data[vertex_1] + + clifford_1_table_code = asg.sqp[vertex_1] + 4 * (asg.sqs[vertex_1] - 1) + clifford_2_table_code = asg.sqp[vertex_2] + 4 * (asg.sqs[vertex_2] - 1) + table_tuple = cz_table[connected+1][clifford_1_table_code, clifford_2_table_code] + + connected != table_tuple[1] && toggle_edge!(asg.edge_data, vertex_1, vertex_2) + asg.sqp[vertex_1] = table_tuple[2][1] + asg.sqs[vertex_1] = table_tuple[2][2] + asg.sqp[vertex_2] = table_tuple[3][1] + asg.sqs[vertex_2] = table_tuple[3][2] +end + + +""" +Remove all single qubit clifford operations on a vertex v that do not +commute with CZ. Needs use of a neighbor of v, but if we wish to avoid +using a particular neighbor, we can specify it. + +Args: + sqs::Vector{UInt8} single qubit clifford operations on each node + adj::Vector{AdjList} adjacency list describing the graph state + v::Int index of the vertex to remove single qubit clifford operations from + avoid::Int index of a neighbor of v to avoid using +""" +function remove_sqs!(asg, v, avoid, hyperparams) + code = asg.sqs[v] + if code == I_code || code == S_code + elseif code == SQRT_X_code || code == HS_code + local_complement!(asg, v) + else # code == H_code || code == SH_code + # almost all calls to remove_sqs!() will end up here + neighbor = get_neighbor(asg.edge_data, v, avoid, hyperparams) + local_complement!(asg, neighbor) + local_complement!(asg, v) + end +end + +""" +Select a neighbor to use when removing a single qubit clifford operation. + +The return value be set to avoid if there are no neighbors or avoid is the only neighbor, +otherwise it returns the neighbor with the fewest neighbors (or the first one that +it finds with less than min_neighbor_degree) +""" +function get_neighbor(adj, v, avoid, hyperparams) + neighbors_of_v = adj[v] + + # Avoid copying and modifying adjacency vector + check_almost_isolated(neighbors_of_v, avoid) && return avoid + + smallest_neighborhood_size = typemax(eltype(neighbors_of_v)) # initialize to max possible value + neighbor_with_smallest_neighborhood = 0 + if length(neighbors_of_v) <= hyperparams.max_num_neighbors_to_search + neighbors_to_search = neighbors_of_v + else + neighbors_to_search = sample( + collect(neighbors_of_v), + hyperparams.max_num_neighbors_to_search; + replace=false + ) + end + + for neighbor in neighbors_to_search + if neighbor != avoid + # stop search if super small neighborhood is found + num_neighbors = length(adj[neighbor]) + num_neighbors < hyperparams.min_neighbor_degree && return neighbor + # search for smallest neighborhood + if num_neighbors < smallest_neighborhood_size + smallest_neighborhood_size = num_neighbors + neighbor_with_smallest_neighborhood = neighbor + end + end + end + return neighbor_with_smallest_neighborhood +end + + +""" +Take the local complement of a vertex v. + +Args: + sqs::Vector{UInt8} single qubit clifford operations on each node + adj::Vector{AdjList} adjacency list describing the graph state + v::Int index node to take the local complement of +""" +function local_complement!(asg, v) + neighbors = collect(asg.edge_data[v]) + len = length(neighbors) + multiply_sqrt_x_from_right(asg, v) + for i = 1:len + neighbor = neighbors[i] + multiply_s_dagger_from_right(asg, neighbor) + for j = i+1:len + toggle_edge!(asg.edge_data, neighbor, neighbors[j]) + end + end +end + + +"""Add an edge between the two vertices given""" +@inline function add_edge!(adj, vertex_1, vertex_2) + push!(adj[vertex_1], vertex_2) + push!(adj[vertex_2], vertex_1) +end + +"""Remove an edge between the two vertices given""" +@inline function remove_edge!(adj, vertex_1, vertex_2) + delete!(adj[vertex_1], vertex_2) + delete!(adj[vertex_2], vertex_1) +end + +""" +If vertices vertex_1 and vertex_2 are connected, we remove the edge. +Otherwise, add it. + +Args: + adj::Vector{AdjList} adjacency list describing the graph state + vertex_1::Int index of vertex to be connected or disconnected + vertex_2::Int index of vertex to be connected or disconnected +""" +function toggle_edge!(adj, vertex_1, vertex_2) + if vertex_2 in adj[vertex_1] + remove_edge!(adj, vertex_1, vertex_2) + else + add_edge!(adj, vertex_1, vertex_2) + end +end + +""" +Teleport your "oz qubit" with high degree to a "kansas qubit" with degree 1. +Speeds up computation by avoiding performing local complements on high degree nodes. + +Args: + asg::AlgorithmSpecificGraph graph state to teleport in + oz_qubit::Int index of the qubit to teleport + pauli_tracker::PauliTracker tracker to update with teleportation + hyperparams::RbSHyperparams metaparameters which can be optimized to speed up the compilation + curr_teleportation_distance::Int number of teleportations to do when state is teleported + multiplied by 2 +""" +function teleportation!( + asg, + oz_qubit, + pauli_tracker, + hyperparams, + curr_teleportation_distance, +) + slippers_qubit = Qubit(asg.n_nodes + 1) # facilitates teleportation + kansas_qubit = Qubit(asg.n_nodes + 2) # qubit we teleport to + asg.n_nodes += 2 + add_new_qubit_to_pauli_tracker!(pauli_tracker) + add_new_qubit_to_pauli_tracker!(pauli_tracker) + + # output state of H(slippers_qubit) * CX(slippers_qubit, kansas_qubit_qubit) * H(slippers_qubit) + asg.sqs[slippers_qubit] = I_code + asg.sqs[kansas_qubit] = I_code + asg.edge_data[slippers_qubit] = AdjList(kansas_qubit) + asg.edge_data[kansas_qubit] = AdjList(slippers_qubit) + + cz_no_teleport(asg, oz_qubit, slippers_qubit, pauli_tracker, hyperparams) + multiply_h_from_left(asg, pauli_tracker, slippers_qubit) + multiply_h_from_left(asg, pauli_tracker, oz_qubit) + + add_z_to_pauli_tracker!(pauli_tracker.cond_paulis, oz_qubit, kansas_qubit) + add_measurement!(pauli_tracker.measurements, H_code, oz_qubit) + add_x_to_pauli_tracker!(pauli_tracker.cond_paulis, slippers_qubit, kansas_qubit) + add_measurement!(pauli_tracker.measurements, H_code, slippers_qubit) + + + # update qubit map if needed + for (i, qubit) in enumerate(asg.stitching_properties.gate_output_nodes) + if qubit == oz_qubit + asg.stitching_properties.gate_output_nodes[i] = kansas_qubit + end + end + + # peform multiple teleportations if we need distance > 2 + if curr_teleportation_distance > 2 + distance = curr_teleportation_distance - 2 + return teleportation!(asg, kansas_qubit, pauli_tracker, hyperparams, distance) + end + + return kansas_qubit +end diff --git a/src/benchq/compilation/graph_states/ruby_slippers/verbose_iterator.jl b/src/benchq/compilation/graph_states/ruby_slippers/verbose_iterator.jl new file mode 100644 index 00000000..c7b65f6b --- /dev/null +++ b/src/benchq/compilation/graph_states/ruby_slippers/verbose_iterator.jl @@ -0,0 +1,79 @@ +using Base: iterate + +struct VerboseIterable{T} + iterable::T + verbose::Bool + starting_msg::String + python_iterator::Bool + update_frequency::Int +end + +""" +A wrapper around an iteraterable which prints the progress of the iteration. +If the iteration exceeds the max allowable time, the iteration will be stopped. + +Args: + iterable::T The iterable to iterate over + verbose::Bool Whether to print the progress of the function + starting_msg::String Message to print when starting the iteration + python_iterator::Bool Whether the iterator is a python iterator (starts at 0) + +Raises: + ValueError: if an unsupported gate is encountered + +Returns: + VerboseIterable: The iterable wrapped in a VerboseIterable +""" +function VerboseIterator(iterable, verbose, starting_msg="Starting iteration...", python_iterator=false, update_frequency=1000) + VerboseIterable(iterable, verbose, starting_msg, python_iterator, update_frequency) +end + +function Base.iterate(vi::VerboseIterable, state=(1, time(), 0, 0, false)) # Initial state + iterable, verbose, update_frequency = vi.iterable, vi.verbose, vi.update_frequency + idx, start_time, counter, dispcnt, first_item_completed = state + total_length = length(iterable) + + if !first_item_completed + if verbose + println(vi.starting_msg) + end + if vi.python_iterator + idx = 0 # Python iterators start at 0 + end + first_item_completed = true + end + + if idx > total_length || (vi.python_iterator && idx == total_length) + if verbose + elapsed = round(time() - start_time, digits=2) + println("\r100% ($counter) completed in $(elapsed)s") + end + return nothing # Iteration is complete + end + + item = iterable[idx] + idx += 1 + counter += 1 + dispcnt += 1 + + if verbose && dispcnt >= update_frequency + percent = round(Int, 100 * counter / total_length) + elapsed_time = round(time() - start_time, digits=2) + print("\r$(percent)% ($counter) completed in $(elapsed_time)s") + dispcnt = 0 # Reset display counter + end + + return (item, (idx, start_time, counter, dispcnt, first_item_completed)) +end + +@inline update_verbose_iterator_display(counter, total_length, start_time, dispcnt, verbose) = begin + counter += 1 + dispcnt += 1 + + if verbose && dispcnt >= 1000 + percent = round(Int, 100 * counter / total_length) + elapsed_time = round(time() - start_time, digits=2) + print("\r$(percent)% ($counter) completed in $(elapsed_time)s") + dispcnt = 0 # Reset display counter + end +end \ No newline at end of file diff --git a/src/benchq/compilation/graph_states/substrate_scheduler/python_substrate_scheduler.py b/src/benchq/compilation/graph_states/substrate_scheduler/python_substrate_scheduler.py new file mode 100644 index 00000000..fe699ed9 --- /dev/null +++ b/src/benchq/compilation/graph_states/substrate_scheduler/python_substrate_scheduler.py @@ -0,0 +1,68 @@ +import time + +import networkx as nx +from graph_state_generation.optimizers import ( + fast_maximal_independent_set_stabilizer_reduction, + greedy_stabilizer_measurement_scheduler, +) +from graph_state_generation.substrate_scheduler import TwoRowSubstrateScheduler + +from benchq.visualization_tools.plot_substrate_scheduling import ( + remove_isolated_nodes_from_graph, +) + + +def python_substrate_scheduler( + asg, preset: str, verbose: bool = False +) -> TwoRowSubstrateScheduler: + """A simple interface for running the substrate scheduler. Can be run quickly or + optimized for smaller runtime. Using the "optimized" preset can halve the number + of measurement steps, but takes about 100x longer to run. It's probably only + suitable for graphs with less than 10^5 nodes. + + Args: + graph (nx.Graph): Graph to create substrate schedule for. + preset (str): Can optimize for speed ("fast") or for smaller number of + measurement steps ("optimized"). + + Returns: + TwoRowSubstrateScheduler: A substrate scheduler object with the schedule + already created. + """ + graph = get_nx_graph_from_adj_list(asg["edge_data"]) + cleaned_graph = remove_isolated_nodes_from_graph(graph)[1] + + if verbose: + print("starting substrate scheduler") + start = time.time() + if preset == "fast": + compiler = TwoRowSubstrateScheduler( + cleaned_graph, + stabilizer_scheduler=greedy_stabilizer_measurement_scheduler, + ) + if preset == "optimized": + compiler = TwoRowSubstrateScheduler( + cleaned_graph, + pre_mapping_optimizer=fast_maximal_independent_set_stabilizer_reduction, + stabilizer_scheduler=greedy_stabilizer_measurement_scheduler, + ) + compiler.run() + end = time.time() + if verbose: + print("substrate scheduler took", end - start, "seconds") + return compiler + + +def get_n_measurement_steps(optimization, graph, verbose: bool = False) -> int: + compiler = python_substrate_scheduler(graph, optimization, verbose) + n_measurement_steps = len(compiler.measurement_steps) + return n_measurement_steps + + +def get_nx_graph_from_adj_list(adj: list) -> nx.Graph: + graph = nx.empty_graph(len(adj)) + for vertex_id, neighbors in enumerate(adj): + for neighbor in neighbors: + graph.add_edge(vertex_id, neighbor) + + return graph diff --git a/src/benchq/compilation/graph_states/substrate_scheduler/substrate_scheduler.jl b/src/benchq/compilation/graph_states/substrate_scheduler/substrate_scheduler.jl new file mode 100644 index 00000000..95acf073 --- /dev/null +++ b/src/benchq/compilation/graph_states/substrate_scheduler/substrate_scheduler.jl @@ -0,0 +1,242 @@ +# This file contains the functions to schedule the measurements of a graph state on a quantum computer. +# This file is not well tested as Athena did not have time to write tests for it. It is also not well documented +# so you might want to reach out to her if you have questions on how it works. + +function two_row_scheduler(asg, pauli_tracker, num_logical_qubits, optimization, verbose=false) + if optimization == "Time" + return time_optimal_two_row_scheduler(asg, pauli_tracker, num_logical_qubits, verbose) + elseif optimization == "Space" + return space_optimal_two_row_scheduler(asg, pauli_tracker, num_logical_qubits, verbose) + elseif optimization == "Variable" + return space_optimal_two_row_scheduler(asg, pauli_tracker, num_logical_qubits, verbose) + else + throw(ArgumentError("Invalid optimization type.")) + end +end + +function get_max_independent_set(asg) + # Initialize an empty set to store the maximal independent set + independent_set = Set{Int}() + + # Create an array to keep track of the state of each vertex (included or not) + included = falses(asg.n_nodes) + + # Iterate over each vertex in the graph + for v in 1:asg.n_nodes + # Check if the vertex is not included and its neighbors are not included + if !included[v] && all(!included[neighbor] for neighbor in asg.edge_data[v]) + # Add the vertex to the independent set + push!(independent_set, v) + # Mark the vertex as included + included[v] = true + end + end + + return independent_set +end + +function time_optimal_two_row_scheduler(asg, pauli_tracker, num_logical_qubits, verbose=false) + # Here we use the procedure of https://arxiv.org/abs/2306.03758 to schedule measurements + # We choose to skip phase 3 of the optimization. Because it is costly in terms of compilation + # time and does not provide a significant improvement in the number of tocks required. + + # Phase 1: We can choose to ignore the nodes in a maximal independent set of the graph + # as they can be initialized in a way that satisfies the stabilizers of the graph state + nodes_satisfied_by_initialization = get_max_independent_set(asg) + + curr_physical_nodes = get_neighborhood(pauli_tracker.layering[1], asg, 2) + measured_nodes = Set{Qubit}([]) + new_nodes_to_add = curr_physical_nodes + satisfied_nodes = Set{Qubit}([]) + + patches_to_node = [-1 for _ in 1:num_logical_qubits] + node_to_patch = [-1 for _ in 1:asg.n_nodes] + + num_tocks_for_graph_creation = [0 for _ in 1:length(pauli_tracker.layering)] + num_t_states_per_layer = [0 for _ in 1:length(pauli_tracker.layering)] + num_rotations_per_layer = [0 for _ in 1:length(pauli_tracker.layering)] + + for layer_num in VerboseIterator(1:length(pauli_tracker.layering), verbose, "Scheduling Clifford operations...") + # assign nodes to patches randomly by simply finding the first open patch and placing the node there + for new_node in new_nodes_to_add + node_placement_found = false + for (patch, node_in_patch) in enumerate(patches_to_node) + if node_in_patch == -1 + patches_to_node[patch] = new_node + node_to_patch[new_node] = patch + node_placement_found = true + break + end + end + if !node_placement_found + println("Error: No patch found for node ", new_node) + end + end + + # Phase 2: Schedule the multi-qubit measurements for each of the remaining stabilizers of the graph state + # which correspond to nodes in the graph. + + # get the bar for each node we are measuring in this layer + nodes_to_satisfy_this_layer = setdiff(get_neighborhood(pauli_tracker.layering[layer_num], asg), satisfied_nodes) + union!(satisfied_nodes, nodes_to_satisfy_this_layer) + bars = [] + for node in setdiff(nodes_to_satisfy_this_layer, nodes_satisfied_by_initialization) + bar = [node_to_patch[node], node_to_patch[node]] + for neighbor in asg.edge_data[node] + if node_to_patch[neighbor] < bar[1] & node in curr_physical_nodes + bar[1] = node_to_patch[neighbor] + end + if node_to_patch[neighbor] > bar[2] & node in curr_physical_nodes + bar[2] = node_to_patch[neighbor] + end + end + push!(bars, bar) + if pauli_tracker.measurements[node][1] in [T_code, T_Dagger_code] + num_t_states_per_layer[layer_num] += 1 + end + if pauli_tracker.measurements[node][1] == RZ_code + num_rotations_per_layer[layer_num] += 1 + end + end + sort!(bars, by=x -> x[2]) + + # layer the bars + while length(bars) > 0 + bar = bars[1] + bars = bars[2:end] + i = 1 + bars_length = length(bars) + while i <= bars_length + if bars[i][1] > bar[2] + bar[2] = bars[i][2] + deleteat!(bars, i) + bars_length -= 1 + end + i += 1 + end + num_tocks_for_graph_creation[layer_num] += 1 + end + + if layer_num < length(pauli_tracker.layering) + union!(measured_nodes, pauli_tracker.layering[layer_num]) + for measured_node in pauli_tracker.layering[layer_num] + patches_to_node[node_to_patch[measured_node]] = -1 + end + added_nodes = pauli_tracker.layering[layer_num+1] + + setdiff!(curr_physical_nodes, pauli_tracker.layering[layer_num]) + new_nodes_to_add = setdiff(setdiff(get_neighborhood(added_nodes, asg, 2), measured_nodes), curr_physical_nodes) + union!(curr_physical_nodes, new_nodes_to_add) + end + end + + verbose && println("num_tocks_for_graph_creation: ", sum(num_tocks_for_graph_creation)) + + return num_tocks_for_graph_creation, num_t_states_per_layer, num_rotations_per_layer +end + +function space_optimal_two_row_scheduler(asg, pauli_tracker, num_logical_qubits, verbose=false) + # In this strategy we simply apply the cz gates that are requires in order to create the graph state + curr_physical_nodes = get_neighborhood(pauli_tracker.layering[1], asg) + measured_nodes = Set{Qubit}([]) + new_nodes_to_add = curr_physical_nodes + satisfied_edges = copy(asg.edge_data) + + patches_to_node = [-1 for _ in 1:num_logical_qubits] + node_to_patch = [-1 for _ in 1:asg.n_nodes] + + num_tocks_for_graph_creation = [0 for _ in 1:length(pauli_tracker.layering)] + num_t_states_per_layer = [0 for _ in 1:length(pauli_tracker.layering)] + num_rotations_per_layer = [0 for _ in 1:length(pauli_tracker.layering)] + + for layer_num in VerboseIterator(1:length(pauli_tracker.layering), verbose, "Scheduling Clifford operations...") + # assign nodes to patches by simply finding the first open patch and placing the node there + # println("Assigning Nodes to Patches...") + begin + for new_node in new_nodes_to_add + node_placement_found = false + for (patch, node_in_patch) in enumerate(patches_to_node) + if node_in_patch == -1 + patches_to_node[patch] = new_node + node_to_patch[new_node] = patch + node_placement_found = true + break + end + end + if !node_placement_found + println("Error: No patch found for node ", new_node) + end + end + end + + # Enact each of the edges of the graph individually + # println("layer_num: ", layer_num) + # println("Getting Bars...") + begin + bars = [] + for node in pauli_tracker.layering[layer_num] + for neighbor in asg.edge_data[node] + if neighbor in satisfied_edges[node] && node in satisfied_edges[neighbor] + toggle_edge!(satisfied_edges, node, neighbor) + push!(bars, [node_to_patch[node], node_to_patch[neighbor]]) + end + end + end + end + # println("nodes_to_satisfy_this_layer: ", Set([Int(x) for x in pauli_tracker.layering[layer_num]])) + # println("patches_to_node: ", patches_to_node) + + sort!(bars, by=x -> x[2]) + + # layer the bars to parallelize them + # println("bars: ", bars) + # println("Layering Bars...") + begin + while length(bars) > 0 + bar = bars[1] + bars = bars[2:end] + i = 1 + bars_length = length(bars) + while i <= bars_length + if bars[i][1] > bar[2] + bar[2] = bars[i][2] + deleteat!(bars, i) + bars_length -= 1 + end + i += 1 + end + num_tocks_for_graph_creation[layer_num] += 1 + end + # each cz requires 2 tocks + num_tocks_for_graph_creation[layer_num] *= 2 + end + + for node in pauli_tracker.layering[layer_num] + if pauli_tracker.measurements[node][1] in [T_code, T_Dagger_code] + num_t_states_per_layer[layer_num] += 1 + end + if pauli_tracker.measurements[node][1] == RZ_code + num_rotations_per_layer[layer_num] += 1 + end + end + + # println("preparing for next layer") + begin + if layer_num < length(pauli_tracker.layering) + union!(measured_nodes, pauli_tracker.layering[layer_num]) + for measured_node in pauli_tracker.layering[layer_num] + patches_to_node[node_to_patch[measured_node]] = -1 + end + added_nodes = pauli_tracker.layering[layer_num+1] + + setdiff!(curr_physical_nodes, pauli_tracker.layering[layer_num]) + new_nodes_to_add = setdiff(setdiff(get_neighborhood(added_nodes, asg), measured_nodes), curr_physical_nodes) + union!(curr_physical_nodes, new_nodes_to_add) + end + end + end + + verbose && println("num_tocks_for_graph_creation: ", sum(num_tocks_for_graph_creation)) + + return num_tocks_for_graph_creation, num_t_states_per_layer, num_rotations_per_layer +end diff --git a/src/benchq/compilation/graph_states/table_generation/README.md b/src/benchq/compilation/graph_states/table_generation/README.md new file mode 100644 index 00000000..309548b3 --- /dev/null +++ b/src/benchq/compilation/graph_states/table_generation/README.md @@ -0,0 +1 @@ +This folder contains files which were used to generate the tables in graph_sim_data. \ No newline at end of file diff --git a/src/benchq/compilation/graph_states/table_generation/generate_clifford_tables.jl b/src/benchq/compilation/graph_states/table_generation/generate_clifford_tables.jl new file mode 100644 index 00000000..1ad15f6d --- /dev/null +++ b/src/benchq/compilation/graph_states/table_generation/generate_clifford_tables.jl @@ -0,0 +1,62 @@ +# numbers which correspond to each of the gates in multiply_sqs +const I_code = UInt8(1) +const S_code = UInt8(2) +const H_code = UInt8(3) +const SQRT_X_code = UInt8(4) +const HSH_code = UInt8(4) # e^{iπ/4} X HSH = SHS +const SH_code = UInt8(5) # Apply H first, then S +const HS_code = UInt8(6) # Apply S first, then H + +# Singe qubit Paulis +# external codes which must be distinct from the symplectic codes +const X_code = UInt8(7) +const Y_code = UInt8(8) +const Z_code = UInt8(9) + +# Internal codes for the paulis. Allows for faster manipulation and simplifies debugging +const I_code_internal = UInt8(1) +const X_code_internal = UInt8(2) +const Y_code_internal = UInt8(3) +const Z_code_internal = UInt8(4) + +const external_to_internal_paulis = Dict( + I_code => I_code, X_code => X_code_internal, Y_code => Y_code_internal, Z_code => Z_code_internal +) + +const multiply_sqp = [ + 1 2 3 4 + 2 1 4 3 + 3 4 1 2 + 4 3 2 1 +] + +update_pauli_from_S_from_left = zeros(Int, 4, 6) +const conj_pauli_by_S = [1, 3, 2, 4] +excess_pauli_S_left = [I_code, Z_code_internal, I_code, X_code_internal, Z_code_internal, X_code_internal] +for i in range(1, 4) + for j in range(1, 6) + update_pauli_from_S_from_left[i, j] = multiply_sqp[conj_pauli_by_S[i], excess_pauli_S_left[j]] + end +end +println(update_pauli_from_S_from_left) + +update_pauli_from_S_from_right = zeros(Int, 4, 6) +excess_pauli_S_right = [Z_code_internal, I_code, X_code_internal, X_code_internal, Z_code_internal, I_code] +for i in range(1, 4) + for j in range(1, 6) + excess_pauli = excess_pauli_S_right[j] + update_pauli_from_S_from_right[i, j] = multiply_sqp[i, excess_pauli] + end +end +println(update_pauli_from_S_from_right) + + +update_pauli_from_SQRT_X_from_right = zeros(Int, 4, 6) +excess_pauli_SQRT_X_right = [I_code, X_code_internal, I_code, X_code_internal, Z_code_internal, Z_code_internal] +for i in range(1, 4) + for j in range(1, 6) + excess_pauli = excess_pauli_SQRT_X_right[j] + update_pauli_from_SQRT_X_from_right[i, j] = multiply_sqp[i, excess_pauli] + end +end +println(update_pauli_from_SQRT_X_from_right) diff --git a/src/benchq/compilation/graph_states/table_generation/generate_cz_table.py b/src/benchq/compilation/graph_states/table_generation/generate_cz_table.py new file mode 100644 index 00000000..7f376e6e --- /dev/null +++ b/src/benchq/compilation/graph_states/table_generation/generate_cz_table.py @@ -0,0 +1,174 @@ +import numpy as np + +I = np.matrix([[1, 0], [0, 1]]) # noqa: E741 + +X = np.matrix([[0, 1], [1, 0]]) +Y = np.matrix([[0, -1j], [1j, 0]]) +Z = np.matrix([[1, 0], [0, -1]]) + +H = (2**-0.5) * np.matrix([[1, 1], [1, -1]]) +S = np.matrix([[1, 0], [0, 1j]]) # type: ignore + +CZ = np.matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, -1]]) + +ZERO_STATE = np.matrix([[1], [0], [0], [0]]) +START_STATE = np.kron(H, H) * ZERO_STATE + +SQS = {"I": I, "S": S, "H": H, "HSH": H * S * H, "SH": S * H, "HS": H * S} +SQP = {"I": I, "X": X, "Y": Y, "Z": Z} + + +def mat_conj(mat1, mat2): + # conjuate matrix 1 by matrix 2 + return mat2 * mat1 * np.conj(mat2).T + + +score_symplectic = {"I": 400, "S": 400, "H": 100, "HSH": 200, "SH": 100, "HS": 200} +score_pauli = {"I": 5, "X": 1, "Y": 0, "Z": 1} + +all_sqc = [] +for S1_name, S1 in SQS.items(): + for P1_name, P1 in SQP.items(): + all_sqc += [(S1_name, S1, P1_name, P1)] + +all_stab_group_perms = [] +perms = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] +for connected_before_cz_was_applied in [False, True]: + # order qubit 2 first to optimize for best operations on 2nd qubit + for S1_name, S1, P1_name, P1 in all_sqc: + for S2_name, S2, P2_name, P2 in all_sqc: + clif = np.kron(P1 * S1, P2 * S2) + if connected_before_cz_was_applied: + clif = clif * CZ + stab_1 = mat_conj(np.kron(X, I), clif) + stab_2 = mat_conj(np.kron(I, X), clif) + full_stab_group = [stab_1, stab_2, stab_1 * stab_2] + for perm in perms: + trial_stab_group_perm = np.array( + [np.round(full_stab_group[i - 1], 7) for i in perm] + ) + all_stab_group_perms += [ + ( + connected_before_cz_was_applied, + S1_name, + P1_name, + S2_name, + P2_name, + trial_stab_group_perm, + ) + ] + +cz_conj_pauli = { + ("I", "I"): ("I", "I"), + ("I", "X"): ("Z", "X"), + ("I", "Y"): ("Z", "Y"), + ("I", "Z"): ("I", "Z"), + ("X", "I"): ("X", "Z"), + ("X", "X"): ("Y", "Y"), + ("X", "Y"): ("Y", "X"), + ("X", "Z"): ("X", "I"), + ("Y", "I"): ("Y", "Z"), + ("Y", "X"): ("X", "Y"), + ("Y", "Y"): ("X", "X"), + ("Y", "Z"): ("Y", "I"), + ("Z", "I"): ("Z", "I"), + ("Z", "X"): ("I", "X"), + ("Z", "Y"): ("I", "Y"), + ("Z", "Z"): ("Z", "Z"), +} + +pauli_mult_table = { + ("I", "I"): "I", + ("I", "X"): "X", + ("I", "Y"): "Y", + ("I", "Z"): "Z", + ("X", "I"): "X", + ("X", "X"): "I", + ("X", "Y"): "Z", + ("X", "Z"): "Y", + ("Y", "I"): "Y", + ("Y", "X"): "Z", + ("Y", "Y"): "I", + ("Y", "Z"): "X", + ("Z", "I"): "Z", + ("Z", "X"): "Y", + ("Z", "Y"): "X", + ("Z", "Z"): "I", +} + +for connected_before_cz_was_applied in [False, True]: + best_combo_strings = "" + for S1_name, S1, P1_name, P1 in all_sqc: + for S2_name, S2, P2_name, P2 in all_sqc: + print( + f"CZ on {S1_name} x {P1_name} {S2_name} x {P2_name} " + f"with {connected_before_cz_was_applied} on diagonal:" + ) + + trial_S1_must_commute_with_CZ = S1_name in ["I", "S"] + trial_S2_must_commute_with_CZ = S2_name in ["I", "S"] + + # commute CZ past P1 and P2 + conj_P1_name, conj_P2_name = cz_conj_pauli[(P1_name, P2_name)] + # Now we only worry about the symplectic parts interaction with CZ + clif = CZ * np.kron(S1, S2) + if connected_before_cz_was_applied: + clif = clif * CZ + stab_1 = mat_conj(np.kron(X, I), clif) + stab_2 = mat_conj(np.kron(I, X), clif) + full_stab_group = np.array( + [stab_1, stab_2, stab_1 * stab_2] + ) # type: ignore + + do_break = ( + connected_before_cz_was_applied and S1_name == "H" and S2_name == "H" + ) + + combo_desirability = 0 + for ( + trial_connected_before_cz_was_applied, + trial_S1_name, + trial_P1_name, + trial_S2_name, + trial_P2_name, + trial_stab_group_perm, + ) in all_stab_group_perms: + if trial_S1_must_commute_with_CZ: + if trial_S1_name not in ["I", "S"]: + continue + if trial_P1_name not in ["I", "Z"]: + continue + if trial_S2_must_commute_with_CZ: + if trial_S2_name not in ["I", "S"]: + continue + if trial_P2_name not in ["I", "Z"]: + continue + if np.allclose(full_stab_group, trial_stab_group_perm, atol=1e-5): + final_P1_name = pauli_mult_table[conj_P1_name, trial_P1_name] + final_P2_name = pauli_mult_table[conj_P2_name, trial_P2_name] + if do_break: + breakpoint() + new_combo_desirability = ( + score_symplectic[trial_S1_name] + + score_symplectic[trial_S2_name] + + score_pauli[final_P1_name] + + score_pauli[final_P2_name] + ) + if new_combo_desirability > combo_desirability: + combo_desirability = new_combo_desirability + if trial_connected_before_cz_was_applied: + trial_diagonal_string = "1" + else: + trial_diagonal_string = "0" + best_combo_string = ( + f"({trial_diagonal_string}, " + f"({final_P1_name}_code_internal, {trial_S1_name}_code), " + f"({final_P2_name}_code_internal, {trial_S2_name}_code)) " + ) + + if combo_desirability == 0: + raise ValueError("No match found") + best_combo_strings += best_combo_string + best_combo_strings += "\n" + + print(best_combo_strings + "\n\n") diff --git a/src/benchq/compilation/graph_states/table_generation/graph_states_equivalent_to_bell_state.py b/src/benchq/compilation/graph_states/table_generation/graph_states_equivalent_to_bell_state.py new file mode 100644 index 00000000..d611176a --- /dev/null +++ b/src/benchq/compilation/graph_states/table_generation/graph_states_equivalent_to_bell_state.py @@ -0,0 +1,121 @@ +import numpy as np + +I = np.matrix([[1, 0], [0, 1]]) # noqa: E741 + +X = np.matrix([[0, 1], [1, 0]]) +Y = np.matrix([[0, -1j], [1j, 0]]) +Z = np.matrix([[1, 0], [0, -1]]) + +H = (2**-0.5) * np.matrix([[1, 1], [1, -1]]) +S = np.matrix([[1, 0], [0, 1j]]) # type: ignore + +CZ = np.matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, -1]]) + +ZERO_STATE = np.matrix([[1], [0], [0], [0]]) +START_STATE = np.kron(H, H) * ZERO_STATE + +SQS = {"I": I, "S": S, "H": H, "HSH": H * S * H, "SH": S * H, "HS": H * S} +SQP = {"I": I, "X": X, "Y": Y, "Z": Z} + + +def mat_conj(mat1, mat2): + # conjuate matrix 1 by matrix 2 + return mat2 * mat1 * np.conj(mat2).T + + +score_symplectic = {"I": 400, "S": 400, "H": 100, "HSH": 200, "SH": 100, "HS": 200} +score_pauli = {"I": 5, "X": 1, "Y": 0, "Z": 1} + +all_sqc = [] +for S1_name, S1 in SQS.items(): + for P1_name, P1 in SQP.items(): + all_sqc += [(S1_name, S1, P1_name, P1)] + +all_stab_group_perms = [] +perms = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] +for connected_before_cz_was_applied in [False, True]: + # order qubit 2 first to optimize for best operations on 2nd qubit + for S1_name, S1, P1_name, P1 in all_sqc: + for S2_name, S2, P2_name, P2 in all_sqc: + clif = np.kron(P1 * S1, P2 * S2) + if connected_before_cz_was_applied: + clif = clif * CZ + stab_1 = mat_conj(np.kron(X, I), clif) + stab_2 = mat_conj(np.kron(I, X), clif) + full_stab_group = [stab_1, stab_2, stab_1 * stab_2] + for perm in perms: + trial_stab_group_perm = np.array( + [np.round(full_stab_group[i - 1], 7) for i in perm] + ) + all_stab_group_perms += [ + ( + connected_before_cz_was_applied, + S1_name, + P1_name, + S2_name, + P2_name, + trial_stab_group_perm, + ) + ] + +cz_conj_pauli = { + ("I", "I"): ("I", "I"), + ("I", "X"): ("Z", "X"), + ("I", "Y"): ("Z", "Y"), + ("I", "Z"): ("I", "Z"), + ("X", "I"): ("X", "Z"), + ("X", "X"): ("Y", "Y"), + ("X", "Y"): ("Y", "X"), + ("X", "Z"): ("X", "I"), + ("Y", "I"): ("Y", "Z"), + ("Y", "X"): ("X", "Y"), + ("Y", "Y"): ("X", "X"), + ("Y", "Z"): ("Y", "I"), + ("Z", "I"): ("Z", "I"), + ("Z", "X"): ("I", "X"), + ("Z", "Y"): ("I", "Y"), + ("Z", "Z"): ("Z", "Z"), +} + +pauli_mult_table = { + ("I", "I"): "I", + ("I", "X"): "X", + ("I", "Y"): "Y", + ("I", "Z"): "Z", + ("X", "I"): "X", + ("X", "X"): "I", + ("X", "Y"): "Z", + ("X", "Z"): "Y", + ("Y", "I"): "Y", + ("Y", "X"): "Z", + ("Y", "Y"): "I", + ("Y", "Z"): "X", + ("Z", "I"): "Z", + ("Z", "X"): "Y", + ("Z", "Y"): "X", + ("Z", "Z"): "I", +} + +clif = np.kron(H, H) * CZ +stab_1 = mat_conj(np.kron(X, I), clif) +stab_2 = mat_conj(np.kron(I, X), clif) +full_stab_group = np.array([stab_1, stab_2, stab_1 * stab_2]) # type: ignore +for ( + trial_connected_before_cz_was_applied, + trial_S1_name, + trial_P1_name, + trial_S2_name, + trial_P2_name, + trial_stab_group_perm, +) in all_stab_group_perms: + if np.allclose(full_stab_group, trial_stab_group_perm, atol=1e-5): + final_P1_name = pauli_mult_table["I", trial_P1_name] + final_P2_name = pauli_mult_table["I", trial_P2_name] + + print( + trial_connected_before_cz_was_applied, + trial_S1_name, + trial_P1_name, + trial_S2_name, + trial_P2_name, + ) diff --git a/src/benchq/compilation/jabalizer_wrapper.jl b/src/benchq/compilation/jabalizer_wrapper.jl deleted file mode 100644 index eb5a0cf3..00000000 --- a/src/benchq/compilation/jabalizer_wrapper.jl +++ /dev/null @@ -1,92 +0,0 @@ -using Jabalizer - -### ICM PART STARTS HERE - -icm_compile(circuit, n_qubits) = - Jabalizer.compile(circuit, n_qubits, ["T", "T_Dagger", "RX", "RY", "RZ"]) - -### JABALIZER PART STARTS HERE - -function out_cnt(opcnt, prevcnt, tn, pt, t0) - print(" Ops: $opcnt ($(opcnt-prevcnt)), ") - print("elapsed: $(round((tn-t0)/60_000_000_000, digits=2)) min (") - println(round((tn - pt) / 1_000_000_000, digits = 2), " s)") -end - -function map_qubits(num_qubits, icm_output) - qubit_map = Dict{String,Int}() - for qubit = 1:num_qubits - qubit_map[string(qubit - 1)] = qubit - end - for (op_name, op_qubits) in icm_output - for qindex in op_qubits - if !haskey(qubit_map, qindex) - qubit_map[qindex] = (num_qubits += 1) - end - end - end - num_qubits, qubit_map -end - -function prepare(num_qubits, qubit_map, icm_output, debug_flag = false) - state = zero_state(num_qubits) - chkcnt = prevbits = prevop = opcnt = 0 - pt = t0 = time_ns() - # loops over all operations in the circuit and applies them to the state - for (op_name, op_qubits) in icm_output - opcnt += 1 - len = length(op_qubits) - if len == 1 - (Jabalizer.gate_map[op_name](qubit_map[op_qubits[1]]))(state) - elseif len == 2 - (Jabalizer.gate_map[op_name](qubit_map[op_qubits[1]], qubit_map[op_qubits[2]]))( - state, - ) - else - error("Too many arguments to $op_name: $len") - end - if debug_flag && (chkcnt += 1) > 99 - chkcnt = 0 - if ((tn = time_ns()) - pt >= 60_000_000_000) - out_cnt(opcnt, prevop, tn, pt, t0) - pt, prevop = tn, opcnt - end - end - end - debug_flag && out_cnt(opcnt, prevop, time_ns(), pt, t0) - - state -end - -function run_jabalizer(circuit, debug_flag = false) - # Convert to Julia values - n_qubits = Jabalizer.pyconvert(Int, circuit.n_qubits) - icm_input = Jabalizer.ICMGate[] - for op in circuit.operations - name = Jabalizer.pyconvert(String, op.gate.name) - indices = [string(Jabalizer.pyconvert(Int, qubit)) for qubit in op.qubit_indices] - push!(icm_input, (name, indices)) - end - - if debug_flag - print("ICM compilation: qubits=$n_qubits, gates=$(length(icm_input))\n\t") - @time (icm_output, data_qubits_map) = icm_compile(icm_input, n_qubits) - - (n_qubits, qubit_map) = map_qubits(n_qubits, icm_output) - - print( - "Jabalizer state preparation: qubits=$n_qubits, gates=$(length(icm_output))\n\t", - ) - @time state = prepare(n_qubits, qubit_map, icm_output) - - print("Jabalizer graph generation: $n_qubits\n\t") - @time (svec, op_seq) = graph_as_stabilizer_vector(state) - else - icm_output, data_qubits_map = icm_compile(icm_input, n_qubits) - n_qubits, qubit_map = map_qubits(n_qubits, icm_output) - state = prepare(n_qubits, qubit_map, icm_output) - svec, op_seq = graph_as_stabilizer_vector(state) - end - - return svec, op_seq, icm_output, data_qubits_map -end diff --git a/src/benchq/compilation/julia_utils.py b/src/benchq/compilation/julia_utils.py deleted file mode 100644 index ca8e0fb1..00000000 --- a/src/benchq/compilation/julia_utils.py +++ /dev/null @@ -1,83 +0,0 @@ -################################################################################ -# © Copyright 2022-2023 Zapata Computing Inc. -################################################################################ -import time - -import networkx as nx -from orquestra.quantum.circuits import Circuit - -from .initialize_julia import jl - - -def get_nx_graph_from_rbs_adj_list(adj: list) -> nx.Graph: - graph = nx.empty_graph(len(adj)) - for vertex_id, neighbors in enumerate(adj): - for neighbor in neighbors: - graph.add_edge(vertex_id, neighbor) - - return graph - - -def get_algorithmic_graph_from_ruby_slippers(circuit: Circuit) -> nx.Graph: - lco, adj, _ = jl.run_ruby_slippers(circuit, True) - - print("getting networkx graph from vertices") - start = time.time() - graph = get_nx_graph_from_rbs_adj_list(adj) - end = time.time() - print("time: ", end - start) - - return graph - - -def get_ruby_slippers_compiler( - verbose=True, - max_graph_size=1e7, - teleportation_threshold=40, - min_neighbors=6, - teleportation_distance=4, - max_num_neighbors_to_search=1e5, - decomposition_strategy=1, -): - def _run_compiler(circuit: Circuit) -> nx.Graph: - lco, adj, _ = jl.run_ruby_slippers( - circuit, - verbose, - max_graph_size, - teleportation_threshold, - teleportation_distance, - min_neighbors, - max_num_neighbors_to_search, - decomposition_strategy, - ) - - print("getting networkx graph from vertices") - start = time.time() - graph = get_nx_graph_from_rbs_adj_list(adj) - end = time.time() - print("time: ", end - start) - - return graph - - return _run_compiler - - -def get_algorithmic_graph_from_Jabalizer(circuit: Circuit) -> nx.Graph: - svec, op_seq, icm_output, data_qubits_map = jl.run_jabalizer(circuit) - return create_graph_from_stabilizers(svec) - - -def create_graph_from_stabilizers(svec): - G = nx.Graph() - siz = len(svec) - for i in range(siz): - z = svec[i].Z - for j in range(i + 1, siz): - if z[j]: - G.add_edge(i, j) - return G - - -def get_algorithmic_graph_and_icm_output(circuit): - svec, op_seq, icm_output, data_qubits_map = jl.run_jabalizer(circuit) - return create_graph_from_stabilizers(svec), op_seq, icm_output, data_qubits_map diff --git a/src/benchq/compilation/rbs_hyperparam_tuning.py b/src/benchq/compilation/rbs_hyperparam_tuning.py deleted file mode 100644 index ff4ccb65..00000000 --- a/src/benchq/compilation/rbs_hyperparam_tuning.py +++ /dev/null @@ -1,448 +0,0 @@ -from math import ceil - -import networkx as nx -import optuna -from orquestra.quantum.circuits import Circuit, H - -from ..algorithms.data_structures import GraphPartition -from ..problem_embeddings.quantum_program import QuantumProgram -from ..quantum_hardware_modeling import BASIC_SC_ARCHITECTURE_MODEL -from ..resource_estimators.graph_estimators import GraphResourceEstimator -from . import jl, transpile_to_native_gates -from .julia_utils import get_nx_graph_from_rbs_adj_list - - -def space_time_cost_from_rbs( - rbs_iteration_time: float, - max_allowed_time: float, - space_or_time: str, - circuit: Circuit, - verbose=False, - max_graph_size=None, - teleportation_threshold=40, - teleportation_distance=4, - min_neighbors=6, - max_num_neighbors_to_search=1e5, - decomposition_strategy=1, - circuit_prop_estimate=1.0, -): - """ - Runs Ruby Slippers (RBS) and uses the resulting graph to get estimates - of circuit cost complexity in terms of time, space, or both. This is a - low-level function. Unless you mean to use it, recommended to - use one of the functions beginning with "get_optimal_hyperparams_for_" - - Args: - rbs_iteration_time (float): amount of time to let RBS run for - max_allowed_time (float): maximum time you want RBS to run when you - eventually find the whole graph - space_or_time (str): "space" returns the cost for space, "time" for - time, and "space&time" for both - circuit (Circuit): the circuit to run RBS on - verbose (bool): true for verbose, false for quiet - max_graph_size (int): maximum number of nodes in the graph state - teleportation_threshold (int): RBS hyperparam, see ruby_slippers.jl - teleportation_distance (int): RBS hyperparam, see ruby_slippers.jl - min_neighbors (int): RBS hyperparam, see ruby_slippers.jl - max_num_neighbors_to_search (int): RBS hyperparam, see ruby_slippers.jl - decomposition_strategy (int): RBS hyperparam, see ruby_slippers.jl - circuit_prop_estimate (float): copying a large circuit to julia can take - a long time due to turning it into a string and back, so estimate how - much of the circuit RBS will get through before rbs_iteration_time - runs out, and supply that here to speed up optimization - - Returns: - space_cost (float) OR time_cost (float) when space_or_time == "space" or "time" - (space_cost, time_cost) (float, float) when space_or_time == "space&time" - """ - new_circuit = circuit - if circuit_prop_estimate != 1.0: - num_op = ceil(len(circuit.operations) * circuit_prop_estimate) - new_circuit = Circuit(circuit.operations[:num_op]) - - _, adj, proportion_of_circuit_completed = jl.run_ruby_slippers( - new_circuit, - verbose, - max_graph_size, - teleportation_threshold, - teleportation_distance, - min_neighbors, - max_num_neighbors_to_search, - decomposition_strategy, - rbs_iteration_time, - ) - - if proportion_of_circuit_completed == 1.0 and circuit_prop_estimate != 1.0: - raise RuntimeError( - "Reached the end of rbs iteration with reduced circuit size. Either " - "increase circuit_prop_estimate, decrease rbs_iteration_time, or both." - ) - - estimated_time = rbs_iteration_time / proportion_of_circuit_completed - time_overrun = estimated_time - max_allowed_time - # max value for float is approx 10^308, avoid going past that - if time_overrun > 300: - time_overrun = 300 - - # get graph data - nx_graph = get_nx_graph_from_rbs_adj_list(adj) - # remove isolated nodes - isolated_nodes = list(nx.isolates(nx_graph)) - nx_graph.remove_nodes_from(isolated_nodes) - nx_graph = nx.convert_node_labels_to_integers(nx_graph) - - dummy_circuit = Circuit([H(0)]) - - quantum_program = QuantumProgram( - [dummy_circuit], - 1, - lambda x: [0] * x, - ) - - graph_partition = GraphPartition(program=quantum_program, subgraphs=[nx_graph]) - empty_graph_re = GraphResourceEstimator(BASIC_SC_ARCHITECTURE_MODEL) - graph_data = empty_graph_re._get_graph_data_for_single_graph(graph_partition) - - if space_or_time == "space": - return (10**time_overrun) + graph_data.max_graph_degree - 1 - elif space_or_time == "time": - return (10**time_overrun) + graph_data.n_measurement_steps - 1 - elif space_or_time == "space&time": - return ( - (10**time_overrun) + graph_data.max_graph_degree - 1, - (10**time_overrun) + graph_data.n_measurement_steps - 1, - ) - else: - raise ValueError( - "space_or_time must be 'space', 'time', or 'space&time'." - "Instead got " + str(space_or_time) - ) - - -def estimated_time_cost_from_rbs( - rbs_iteration_time: float, - circuit: Circuit, - verbose=False, - max_graph_size=None, - teleportation_threshold=40, - teleportation_distance=4, - min_neighbors=6, - max_num_neighbors_to_search=1e5, - decomposition_strategy=1, - circuit_prop_estimate=1.0, -): - """ - Runs Ruby Slippers (RBS) and uses the resulting graph to get estimate - of how long RBS would take to compile the whole circuit. This is a - low-level function. Unless you mean to use it, recommended to - use one of the functions beginning with "get_optimal_hyperparams_for_" - - Args: - rbs_iteration_time (float): amount of time to let RBS run for - circuit (Circuit): the circuit to run RBS on - verbose (bool): true for verbose, false for quiet - max_graph_size (int): maximum number of nodes in the graph state - teleportation_threshold (int): RBS hyperparam, see ruby_slippers.jl - teleportation_distance (int): RBS hyperparam, see ruby_slippers.jl - min_neighbors (int): RBS hyperparam, see ruby_slippers.jl - max_num_neighbors_to_search (int): RBS hyperparam, see ruby_slippers.jl - decomposition_strategy (int): RBS hyperparam, see ruby_slippers.jl - circuit_prop_estimate (float): copying a large circuit to julia can take - a long time due to turning it into a string and back, so estimate how - much of the circuit RBS will get through before rbs_iteration_time - runs out, and supply that here to speed up optimization - - Returns: - total estimated time to perform RBS on the whole circuit (float) - """ - new_circuit = circuit - if circuit_prop_estimate != 1.0: - num_op = ceil(len(circuit.operations) * circuit_prop_estimate) - new_circuit = Circuit(circuit.operations[:num_op]) - - _, _, proportion_of_circuit_completed = jl.run_ruby_slippers( - new_circuit, - verbose, - max_graph_size, - teleportation_threshold, - teleportation_distance, - min_neighbors, - max_num_neighbors_to_search, - decomposition_strategy, - rbs_iteration_time, - ) - - return rbs_iteration_time / ( - proportion_of_circuit_completed * circuit_prop_estimate - ) - - -def create_space_time_objective_fn( - rbs_iteration_time: float, - max_allowed_time: float, - space_or_time: str, - circuit: Circuit, - circuit_prop_estimate: float = 1.0, -): - """ - Creates objective function for optuna to use in optimizing for either - space or time. Mid-level function, unless you mean to, recommended to - use one of the functions beginning with "get_optimal_hyperparams_for_" - - Args: - rbs_iteration_time (float): amount of time to let RBS run for - max_allowed_time (float): maximum time you want RBS to run when you - eventually find the whole graph - space_or_time (str): "space" returns the cost for space, "time" for - time, and "space&time" for both - circuit (Circuit): the circuit to run RBS on - circuit_prop_estimate (float): copying a large circuit to julia can take - a long time due to turning it into a string and back, so estimate how - much of the circuit RBS will get through before rbs_iteration_time - runs out, and supply that here to speed up optimization - - Returns: - callable function which accepts an optuna "trial" and returns the cost - """ - - def objective(trial): - teleportation_threshold = trial.suggest_int("teleportation_threshold", 10, 70) - teleportation_distance = trial.suggest_int("teleportation_distance", 1, 7) - min_neighbors = trial.suggest_int("min_neighbors", 1, 11) - max_num_neighbors_to_search = trial.suggest_int( - "max_num_neighbors_to_search", 10000, 100000 - ) - decomposition_strategy = trial.suggest_categorical( - "decomposition_strategy", [0, 1] - ) - - return space_time_cost_from_rbs( - rbs_iteration_time=rbs_iteration_time, - max_allowed_time=max_allowed_time, - space_or_time=space_or_time, - circuit=circuit, - verbose=False, - max_graph_size=None, - teleportation_threshold=teleportation_threshold, - teleportation_distance=teleportation_distance, - min_neighbors=min_neighbors, - max_num_neighbors_to_search=max_num_neighbors_to_search, - decomposition_strategy=decomposition_strategy, - circuit_prop_estimate=circuit_prop_estimate, - ) - - return objective - - -def create_estimated_rbs_time_objective_fn( - rbs_iteration_time: float, - circuit: Circuit, - circuit_prop_estimate: float = 1.0, -): - """ - Creates objective function for optuna to use in optimizing for estimated - total RBS time. Mid-level function, unless you mean to, recommended to - use one of the functions beginning with "get_optimal_hyperparams_for_" - - Args: - rbs_iteration_time (float): amount of time to let RBS run for - circuit (Circuit): the circuit to run RBS on - circuit_prop_estimate (float): copying a large circuit to julia can take - a long time due to turning it into a string and back, so estimate how - much of the circuit RBS will get through before rbs_iteration_time - runs out, and supply that here to speed up optimization - - Returns: - callable function which accepts an optuna "trial" and returns the cost - """ - - def objective(trial): - teleportation_threshold = trial.suggest_int("teleportation_threshold", 10, 70) - teleportation_distance = trial.suggest_int("teleportation_distance", 1, 7) - min_neighbors = trial.suggest_int("min_neighbors", 1, 11) - max_num_neighbors_to_search = trial.suggest_int( - "max_num_neighbors_to_search", 10000, 100000 - ) - decomposition_strategy = trial.suggest_categorical( - "decomposition_strategy", [0, 1] - ) - - return estimated_time_cost_from_rbs( - rbs_iteration_time=rbs_iteration_time, - circuit=circuit, - verbose=False, - max_graph_size=None, - teleportation_threshold=teleportation_threshold, - teleportation_distance=teleportation_distance, - min_neighbors=min_neighbors, - max_num_neighbors_to_search=max_num_neighbors_to_search, - decomposition_strategy=decomposition_strategy, - circuit_prop_estimate=circuit_prop_estimate, - ) - - return objective - - -def get_optimal_hyperparams_for_space( - rbs_iteration_time: float, - max_allowed_time: float, - circuit: Circuit, - n_trials: int, - circuit_prop_estimate: float = 1.0, -): - """ - Function to get optimal hyperparameters for space complexity after running - RBS. - - Args: - rbs_iteration_time (float): amount of time to let RBS run for in each trial - max_allowed_time (float): maximum time you want RBS to run when you - eventually find the whole graph - circuit (Circuit): the circuit to run RBS on - n_trials (int): total number of trials to run when optimizing - circuit_prop_estimate (float): copying a large circuit to julia can take - a long time due to turning it into a string and back, so estimate how - much of the circuit RBS will get through before rbs_iteration_time - runs out, and supply that here to speed up optimization - - Returns: - the best hyperparameters found during optimization - """ - objective = create_space_time_objective_fn( - rbs_iteration_time, - max_allowed_time, - "space", - circuit, - circuit_prop_estimate, - ) - study = optuna.create_study() - study.optimize(objective, n_trials=n_trials) - - return study.best_params - - -def get_optimal_hyperparams_for_time( - rbs_iteration_time: float, - max_allowed_time: float, - circuit: Circuit, - n_trials: int, - circuit_prop_estimate: float = 1.0, -): - """ - Function to get optimal hyperparameters for time complexity after running - RBS. - - Args: - rbs_iteration_time (float): amount of time to let RBS run for in each trial - max_allowed_time (float): maximum time you want RBS to run when you - eventually find the whole graph - circuit (Circuit): the circuit to run RBS on - n_trials (int): total number of trials to run when optimizing - circuit_prop_estimate (float): copying a large circuit to julia can take - a long time due to turning it into a string and back, so estimate how - much of the circuit RBS will get through before rbs_iteration_time - runs out, and supply that here to speed up optimization - - Returns: - the best hyperparameters found during optimization - """ - transpiled_circ = transpile_to_native_gates(circuit) - objective = create_space_time_objective_fn( - rbs_iteration_time, - max_allowed_time, - "time", - transpiled_circ, - circuit_prop_estimate, - ) - study = optuna.create_study() - study.optimize(objective, n_trials=n_trials) - - return study.best_params - - -def get_optimal_hyperparams_for_space_and_time( - rbs_iteration_time: float, - max_allowed_time: float, - circuit: Circuit, - n_trials: int, - space_weight: float = 0.5, - circuit_prop_estimate: float = 1.0, -): - """ - Function to get optimal hyperparameters for both space and time complexity - after running RBS. - - Args: - rbs_iteration_time (float): amount of time to let RBS run for in each trial - max_allowed_time (float): maximum time you want RBS to run when you - eventually find the whole graph - circuit (Circuit): the circuit to run RBS on - n_trials (int): total number of trials to run when optimizing - space_weight (float): between 0 and 1. The closer to 1, the more weight on - the space cost, the closer to 0, the more weight on the time cost - circuit_prop_estimate (float): copying a large circuit to julia can take - a long time due to turning it into a string and back, so estimate how - much of the circuit RBS will get through before rbs_iteration_time - runs out, and supply that here to speed up optimization - - Returns: - the best hyperparameters (based on space_weight) found during optimization - """ - transpiled_circ = transpile_to_native_gates(circuit) - objective = create_space_time_objective_fn( - rbs_iteration_time, - max_allowed_time, - "space&time", - transpiled_circ, - circuit_prop_estimate, - ) - study = optuna.create_study(directions=["minimize", "minimize"]) - study.optimize(objective, n_trials=n_trials) - - best_params = {} - best_score = 100000000 - - for trial in study.best_trials: - # That 5 is based on some observations that (generally) as the best space - # score decreased by 1, the best time score increases by 5. That is, to make - # it closer to an even trade-off, space should be weighted 5x more by - # default and the user can of course adjust using the space_weight param - new_score = trial.values[0] * space_weight * 5 + trial.values[1] * ( - 1 - space_weight - ) - if new_score < best_score: - best_score = new_score - best_params = trial.params - - return best_params - - -def get_optimal_hyperparams_for_estimated_rbs_time( - rbs_iteration_time: float, - circuit: Circuit, - n_trials: int, - circuit_prop_estimate: float = 1.0, -): - """ - Function to get optimal hyperparameters for estimated total time to run RBS - - Args: - rbs_iteration_time (float): amount of time to let RBS run for in each trial - circuit (Circuit): the circuit to run RBS on - n_trials (int): total number of trials to run when optimizing - circuit_prop_estimate (float): copying a large circuit to julia can take - a long time due to turning it into a string and back, so estimate how - much of the circuit RBS will get through before rbs_iteration_time - runs out, and supply that here to speed up optimization - - Returns: - the best hyperparameters found during optimization - """ - transpiled_circ = transpile_to_native_gates(circuit) - objective = create_estimated_rbs_time_objective_fn( - rbs_iteration_time, transpiled_circ, circuit_prop_estimate - ) - study = optuna.create_study() - study.optimize(objective, n_trials=n_trials, catch=(IndexError,)) - - return study.best_params diff --git a/src/benchq/compilation/ruby_slippers.jl b/src/benchq/compilation/ruby_slippers.jl deleted file mode 100644 index d4f78f61..00000000 --- a/src/benchq/compilation/ruby_slippers.jl +++ /dev/null @@ -1,663 +0,0 @@ -################################################################################ -# © Copyright 2022-2023 Zapata Computing Inc. -################################################################################ -#= -This module contains functions for getting the graph state corresponding to a -state generated by a circuit using a graph state simulator (graph_sim) from the paper -"Fast simulation of stabilizer circuits using a graph state representation" by Simon -Anders, Hans J. Briegel. https://arxiv.org/abs/quant-ph/0504117". We have modified -the algorithm to ignore paulis. - -Many of the modules have a no_teleport version. This is to denote that the compiler -does not use teleportation in these cases and is more or less just it's predicessor, -a graph simulator for stabilizer states. -=# - -using PythonCall -using StatsBase - -include("graph_sim_data.jl") - -const AdjList = Set{Int32} - -const Qubit = UInt32 - -struct ICMOp - code::UInt8 - qubit1::Qubit - qubit2::Qubit - - ICMOp(name, qubit) = new(name, qubit, 0) - ICMOp(name, qubit1, qubit2) = new(name, qubit1, qubit2) -end - -struct RubySlippersHyperparams - teleportation_threshold::UInt16 - teleportation_distance::UInt8 - min_neighbors::UInt8 - max_num_neighbors_to_search::UInt32 - decomposition_strategy::UInt8 -end - -default_hyperparams = RubySlippersHyperparams(40, 4, 6, 1e5, 1) - - -""" -Converts a given circuit in Clifford + T form to icm form and simulates the icm -circuit using the graph sim mini simulator. Returns the adjacency list of the graph -state created by the icm circuit along with the single qubit operations on each vertex. -teleportation_threshold, min_neighbors, teleportation_distance, and max_num_neighbors_to_search -are metaparameters which can be optimized to speed up the simulation. - -Args: - circuit::Circuit circuit to be simulated - max_graph_size::Int maximum number of nodes in the graph state - teleportation_threshold::Int max node degree allowed before state is teleported - teleportation_distance::Int number of teleportations to do when state is teleported - min_neighbors::Int stop searching for neighbor with low degree if - neighbor has at least this many neighbors - max_num_neighbors_to_search::Int max number of neighbors to search through when finding - a neighbor with low degree - decomposition_strategy::Int strategy for decomposing non-clifford gate - 0: keep current qubit as data qubit - 1: teleport data to new qubit which becomes data qubit - -Returns: - adj::Vector{AdjList} adjacency list describing the graph state - lco::Vector{UInt8} local clifford operations on each node -""" -function run_ruby_slippers( - circuit, - verbose=false, - max_graph_size=nothing, - teleportation_threshold=40, - teleportation_distance=4, - min_neighbors=6, - max_num_neighbors_to_search=1e5, - decomposition_strategy=1, - max_time=1e8 -) - # params which can be optimized to speed up computation - hyperparams = RubySlippersHyperparams( - teleportation_threshold, - teleportation_distance, - min_neighbors, - max_num_neighbors_to_search, - decomposition_strategy, - ) - - if max_graph_size === nothing - max_graph_size = get_max_n_nodes(circuit, hyperparams.teleportation_distance) - else - max_graph_size = pyconvert(UInt32, max_graph_size) - end - - if verbose - print("get_graph_state_data:\t") - (lco, adj, proportion) = @time get_graph_state_data(circuit, true, max_graph_size, hyperparams, max_time) - else - (lco, adj, proportion) = get_graph_state_data(circuit, false, max_graph_size, hyperparams, max_time) - end - return pylist(lco), python_adjlist!(adj), proportion -end - -function get_max_n_nodes(circuit, teleportation_distance) - supported_ops = get_op_list() - - n_magic_state_injection_teleports = 0 - n_ruby_slippers_teleports = 0 - - for op in circuit.operations - if occursin("ResetOperation", pyconvert(String, op.__str__())) - n_magic_state_injection_teleports += 1 - continue - else - op_index = get_op_index(supported_ops, op) - if double_qubit_op(op_index) - n_ruby_slippers_teleports += 2 - elseif decompose_op(op_index) - n_magic_state_injection_teleports += 1 - n_ruby_slippers_teleports += 1 - end - end - end - - return convert(UInt32, n_magic_state_injection_teleports + - n_ruby_slippers_teleports * teleportation_distance + - pyconvert(Int, circuit.n_qubits)) -end - -""" -Get the vertices of a graph state corresponding to enacting the given circuit -on the |0> state. Also gives the local clifford operation on each node. - -Args: - circuit (Circuit): orquestra circuit circuit to get the graph state for - verbose (Bool): whether to print progress - hyperparams (Dict): metaparameters for the ruby slippers algorithm see - description in run_ruby_slippers for more details - -Raises: - ValueError: if an unsupported gate is encountered - -Returns: - Vector{UInt8}: the list of local clifford operations on each node - Vector{AdjList}: the adjacency list describing the graph corresponding to the graph state -""" -function get_graph_state_data( - circuit, - verbose::Bool=false, - max_graph_size::UInt32=1e8, - hyperparams::RubySlippersHyperparams=default_hyperparams, - max_time::Float64=1e8, -) - - n_qubits = pyconvert(Int, circuit.n_qubits) - ops = circuit.operations - - lco = fill(H_code, max_graph_size) # local clifford operation on each node - adj = [AdjList() for _ = 1:max_graph_size] # adjacency list - if verbose - println("Memory for data structures allocated") - end - - data_qubits = [Qubit(i) for i = 1:n_qubits] - curr_qubits = [n_qubits] # make this a list so it can be modified in place - supported_ops = get_op_list() - - total_length = length(ops) - counter = dispcnt = 0 - erase = " \b\b\b\b\b\b\b\b" - - start_time = time() - - for (i, op) in enumerate(ops) - elapsed = time() - start_time - if elapsed >= max_time - # get rid of excess space in the data structures - resize!(lco, curr_qubits[1]) - resize!(adj, curr_qubits[1]) - - proportion = i / total_length - - return lco, adj, proportion - end - counter += 1 - if verbose - if (dispcnt += 1) >= 1000 - percent = round(Int, 100 * counter / total_length) - display_elapsed = round(elapsed, digits=2) - print("\r$(percent)% ($counter) completed in $erase$(display_elapsed)s") - dispcnt = 0 - end - end - - if occursin("ResetOperation", pyconvert(String, op.__str__())) - curr_qubits[1] += 1 - data_qubits[get_qubit_1(op)] = curr_qubits[1] - continue - else - # Decomposes gates into the icm format. - # Reference: https://arxiv.org/abs/1509.02004 - op_index = get_op_index(supported_ops, op) - if single_qubit_op(op_index) - icm_op = ICMOp(code_list[op_index], data_qubits[get_qubit_1(op)]) - elseif double_qubit_op(op_index) - icm_op = ICMOp( - code_list[op_index], - data_qubits[get_qubit_1(op)], - data_qubits[get_qubit_2(op)], - ) - elseif decompose_op(op_index) - # Note: these are currently all single qubit gates - original_qubit = get_qubit_1(op) - compiled_qubit = data_qubits[original_qubit] - curr_qubits[1] += 1 - if hyperparams.decomposition_strategy == 0 - data_qubits[original_qubit] = curr_qubits[1] - end - icm_op = ICMOp(CNOT_code, compiled_qubit, curr_qubits[1]) - end - end - - # apply the icm_op to the circuit, thereby creating the graph - op_code = icm_op.code - qubit_1 = icm_op.qubit1 - if op_code == H_code - lco[qubit_1] = multiply_h(lco[qubit_1]) - elseif op_code == S_code - lco[qubit_1] = multiply_s(lco[qubit_1]) - elseif op_code == CNOT_code - # CNOT = (I ⊗ H) CZ (I ⊗ H) - qubit_2 = icm_op.qubit2 - lco[qubit_2] = multiply_h(lco[qubit_2]) - cz(lco, adj, qubit_1, qubit_2, data_qubits, curr_qubits, hyperparams) - lco[qubit_2] = multiply_h(lco[qubit_2]) - elseif op_code == CZ_code - cz(lco, adj, qubit_1, icm_op.qubit2, data_qubits, curr_qubits, hyperparams) - elseif !pauli_op(op_code) - error("Unrecognized gate code $op_code encountered") - end - end - - if verbose - elapsed = round(time() - start_time, digits=2) - println("\r100% ($counter) completed in $erase$(elapsed)s") - end - - # get rid of excess space in the data structures - resize!(lco, curr_qubits[1]) - resize!(adj, curr_qubits[1]) - - return lco, adj, 1 -end - -"""Unpacks the values in the cz table and updates the lco values)""" -@inline function update_lco(table, lco, vertex_1, vertex_2) - # Get the packed value from the table - val = table[lco[vertex_1], lco[vertex_2]] - # The code for the first vertex is stored in the top nibble - # and the second in the bottom nibble - lco[vertex_1] = (val >> 4) & 0x7 - lco[vertex_2] = val & 0x7 - # return if the top bit is set, which indicates if it is isolated or connected - (val & 0x80) != 0x00 -end - -""" -Check if a vertex is almost isolated. A vertex is almost isolated if it has no -neighbors or if it has one neighbor and that neighbor is the given vertex. - -Args: - set::AdjList set of neighbors of a vertex - vertex::Int vertex to check if it is almost isolated - -Returns: - Bool: whether the vertex is almost isolated -""" -function check_almost_isolated(set, vertex) - len = length(set) - return (len == 0) || (len == 1 && vertex in set) -end - -""" -Apply a CZ gate to the graph on the given vertices. - -Args: - lco::Vector{UInt8} local clifford operation on each node - adj::Vector{AdjList} adjacency list describing the graph state - vertex_1::Int vertex to enact the CZ gate on - vertex_2::Int vertex to enact the CZ gate on -""" -function cz(lco, adj, vertex_1, vertex_2, data_qubits, curr_qubits, hyperparams) - lst1, lst2 = adj[vertex_1], adj[vertex_2] - - if length(adj[vertex_1]) >= hyperparams.teleportation_threshold - vertex_1 = teleportation!( - lco, - adj, - vertex_1, - data_qubits, - curr_qubits, - hyperparams, - hyperparams.teleportation_distance, - ) - end - if length(adj[vertex_2]) >= hyperparams.teleportation_threshold - vertex_2 = teleportation!( - lco, - adj, - vertex_2, - data_qubits, - curr_qubits, - hyperparams, - hyperparams.teleportation_distance, - ) - end - - - if check_almost_isolated(lst1, vertex_2) - check_almost_isolated(lst2, vertex_1) || - remove_lco!(lco, adj, vertex_2, vertex_1, data_qubits, curr_qubits, hyperparams) - # if you don't remove vertex_2 from lst1, then you don't need to check again - else - remove_lco!(lco, adj, vertex_1, vertex_2, data_qubits, curr_qubits, hyperparams) - if !check_almost_isolated(lst2, vertex_1) - remove_lco!(lco, adj, vertex_2, vertex_1, data_qubits, curr_qubits, hyperparams) - # recheck the adjacency list of vertex_1, because it might have been removed - check_almost_isolated(lst1, vertex_2) || remove_lco!( - lco, - adj, - vertex_1, - vertex_2, - data_qubits, - curr_qubits, - hyperparams, - ) - end - end - if vertex_2 in lst1 - update_lco(cz_connected, lco, vertex_1, vertex_2) || - remove_edge!(adj, vertex_1, vertex_2) - else - update_lco(cz_isolated, lco, vertex_1, vertex_2) && - add_edge!(adj, vertex_1, vertex_2) - end -end - -function cz_no_teleport(lco, adj, vertex_1, vertex_2, data_qubits, curr_qubits, hyperparams) - lst1, lst2 = adj[vertex_1], adj[vertex_2] - - if check_almost_isolated(lst1, vertex_2) - check_almost_isolated(lst2, vertex_1) || remove_lco_no_teleport!( - lco, - adj, - vertex_2, - vertex_1, - data_qubits, - curr_qubits, - hyperparams, - ) - # if you don't remove vertex_2 from lst1, then you don't need to check again - else - remove_lco_no_teleport!( - lco, - adj, - vertex_1, - vertex_2, - data_qubits, - curr_qubits, - hyperparams, - ) - if !check_almost_isolated(lst2, vertex_1) - remove_lco_no_teleport!( - lco, - adj, - vertex_2, - vertex_1, - data_qubits, - curr_qubits, - hyperparams, - ) - # recheck the adjacency list of vertex_1, because it might have been removed - check_almost_isolated(lst1, vertex_2) || remove_lco_no_teleport!( - lco, - adj, - vertex_1, - vertex_2, - data_qubits, - curr_qubits, - hyperparams, - ) - end - end - - if vertex_2 in lst1 - update_lco(cz_connected, lco, vertex_1, vertex_2) || - remove_edge!(adj, vertex_1, vertex_2) - else - update_lco(cz_isolated, lco, vertex_1, vertex_2) && - add_edge!(adj, vertex_1, vertex_2) - end -end - - -""" -Select a neighbor to use when removing a local clifford operation. - -The return value be set to avoid if there are no neighbors or avoid is the only neighbor, -otherwise it returns the neighbor with the fewest neighbors (or the first one that -it finds with less than min_neighbors) -""" -function get_neighbor(adj, v, avoid, hyperparams) - neighbors_of_v = adj[v] - - # Avoid copying and modifying adjacency vector - check_almost_isolated(neighbors_of_v, avoid) && return avoid - - smallest_neighborhood_size = typemax(eltype(neighbors_of_v)) # initialize to max possible value - neighbor_with_smallest_neighborhood = 0 - if length(neighbors_of_v) <= hyperparams.max_num_neighbors_to_search - neighbors_to_search = neighbors_of_v - else - neighbors_to_search = sample( - collect(neighbors_of_v), - hyperparams.max_num_neighbors_to_search; - replace=false - ) - end - for neighbor in neighbors_to_search - if neighbor != avoid - # stop search if super small neighborhood is found - num_neighbors = length(adj[neighbor]) - num_neighbors < hyperparams.min_neighbors && return neighbor - # search for smallest neighborhood - if num_neighbors < smallest_neighborhood_size - smallest_neighborhood_size = num_neighbors - neighbor_with_smallest_neighborhood = neighbor - end - end - end - return neighbor_with_smallest_neighborhood -end - -""" -Remove all local clifford operations on a vertex v that do not commute -with CZ. Needs use of a neighbor of v, but if we wish to avoid using -a particular neighbor, we can specify it. - -Args: - lco::Vector{UInt8} local clifford operations on each node - adj::Vector{AdjList} adjacency list describing the graph state - v::Int index of the vertex to remove local clifford operations from - avoid::Int index of a neighbor of v to avoid using -""" -function remove_lco!(lco, adj, v, avoid, data_qubits, curr_qubits, hyperparams) - code = lco[v] - if code == Pauli_code || code == S_code - elseif code == SQRT_X_code - local_complement!(lco, adj, v, data_qubits, curr_qubits, hyperparams) - else - if code == SH_code - local_complement!(lco, adj, v, data_qubits, curr_qubits, hyperparams) - vb = get_neighbor(adj, v, avoid, hyperparams) - # Cannot use teleportation becase vb wouldn't be a neighbor of v - local_complement_no_teleport!(lco, adj, vb, data_qubits, curr_qubits) - else # code == H_code || code == HS_code - # almost all calls to remove_lco!() will end up here - vb = get_neighbor(adj, v, avoid, hyperparams) - local_complement_no_teleport!(lco, adj, vb, data_qubits, curr_qubits) - local_complement_no_teleport!(lco, adj, v, data_qubits, curr_qubits) - end - end -end - -function remove_lco_no_teleport!(lco, adj, v, avoid, data_qubits, curr_qubits, hyperparams) - code = lco[v] - if code == Pauli_code || code == S_code - elseif code == SQRT_X_code - local_complement_no_teleport!(lco, adj, v, data_qubits, curr_qubits) - else - if code == SH_code - local_complement_no_teleport!(lco, adj, v, data_qubits, curr_qubits) - vb = get_neighbor(adj, v, avoid, hyperparams) - # Cannot use teleportation becase vb wouldn't be a neighbor of v - local_complement_no_teleport!(lco, adj, vb, data_qubits, curr_qubits) - else # code == H_code || code == HS_code - # almost all calls to remove_lco!() will end up here - vb = get_neighbor(adj, v, avoid, hyperparams) - local_complement_no_teleport!(lco, adj, vb, data_qubits, curr_qubits) - local_complement_no_teleport!(lco, adj, v, data_qubits, curr_qubits) - end - end -end - - -""" -Take the local complement of a vertex v. - -Args: - lco::Vector{UInt8} local clifford operations on each node - adj::Vector{AdjList} adjacency list describing the graph state - v::Int index node to take the local complement of -""" -function local_complement!(lco, adj, v, data_qubits, curr_qubits, hyperparams) - - if length(adj[v]) >= hyperparams.teleportation_threshold - v = teleportation!( - lco, - adj, - v, - data_qubits, - curr_qubits, - hyperparams, - hyperparams.teleportation_distance, - ) - end - - local_complement_no_teleport!(lco, adj, v, data_qubits, curr_qubits) -end - -function local_complement_no_teleport!(lco, adj, v, data_qubits, curr_qubits) - neighbors = collect(adj[v]) - len = length(neighbors) - for i = 1:len - neighbor = neighbors[i] - for j = i+1:len - toggle_edge!(adj, neighbor, neighbors[j]) - end - end - lco[v] = multiply_by_sqrt_x(lco[v]) - for i in adj[v] - lco[i] = multiply_by_s(lco[i]) - end -end - - - -"""Add an edge between the two vertices given""" -@inline function add_edge!(adj, vertex_1, vertex_2) - push!(adj[vertex_1], vertex_2) - push!(adj[vertex_2], vertex_1) -end - -"""Remove an edge between the two vertices given""" -@inline function remove_edge!(adj, vertex_1, vertex_2) - delete!(adj[vertex_1], vertex_2) - delete!(adj[vertex_2], vertex_1) -end - -""" -If vertices vertex_1 and vertex_2 are connected, we remove the edge. -Otherwise, add it. - -Args: - adj::Vector{AdjList} adjacency list describing the graph state - vertex_1::Int index of vertex to be connected or disconnected - vertex_2::Int index of vertex to be connected or disconnected -""" -function toggle_edge!(adj, vertex_1, vertex_2) - # if insorted(vertex_2, adj[vertex_1]) - if vertex_2 in adj[vertex_1] - remove_edge!(adj, vertex_1, vertex_2) - else - add_edge!(adj, vertex_1, vertex_2) - end -end - -""" -Teleport your "oz qubit" with high degree to a "kansas qubit" with degree 1. -Speeds up computation by avoiding performing local complements on high degree nodes. - -Args: - lco::Vector{UInt8} local clifford operations on each node - adj::Vector{AdjList} adjacency list describing the graph state - oz_qubit::Int index of the qubit to teleport - data_qubits::Dict map from qubit indices to vertex indices - curr_qubits::Int number of qubits in the graph state -""" -function teleportation!( - lco, - adj, - oz_qubit, - data_qubits, - curr_qubits, - hyperparams, - curr_teleportation_distance, -) - slippers_qubit = Qubit(curr_qubits[1] + 1) # facilitates teleportation - kansas_qubit = Qubit(curr_qubits[1] + 2) # qubit we teleport to - curr_qubits[1] += 2 - - # prepare bell state - adj[slippers_qubit] = AdjList([kansas_qubit]) - adj[kansas_qubit] = AdjList([slippers_qubit]) - lco[slippers_qubit] = SH_code - lco[kansas_qubit] = S_code - - # teleport - lco[slippers_qubit] = multiply_h(lco[slippers_qubit]) - cz_no_teleport( - lco, - adj, - oz_qubit, - slippers_qubit, - data_qubits, - curr_qubits, - hyperparams, - ) - lco[slippers_qubit] = multiply_h(lco[slippers_qubit]) - lco[oz_qubit] = multiply_h(lco[oz_qubit]) - - - # update qubit map if needed - for (i, qubit) in enumerate(data_qubits) - if qubit == oz_qubit - data_qubits[i] = kansas_qubit - end - end - - # peform multiple teleportations if we need distance > 2 - if curr_teleportation_distance > 2 - return teleportation!( - lco, - adj, - kansas_qubit, - data_qubits, - curr_qubits, - hyperparams, - curr_teleportation_distance - 2, - ) - end - - return kansas_qubit -end - - - - -#= -Some small utils for converting from python objects to Julia -=# - -"""Get qubit index of python operation""" -get_qubit_1(op) = pyconvert(Int, op.qubit_indices[0]) + 1 # +1 because Julia is 1-indexed -get_qubit_2(op) = pyconvert(Int, op.qubit_indices[1]) + 1 - -"""Get Python version of op_list of to speed up getting index""" -get_op_list() = pylist(op_list) - -"""Get index of operation name""" -get_op_index(op_list, op) = pyconvert(Int, op_list.index(op.gate.name)) + 1 - -pauli_op(index) = 0 <= index < 5 # i.e. I, X, Y, Z -single_qubit_op(index) = index < 8 # Paulis, H, S, S_Dagger -double_qubit_op(index) = 7 < index < 10 # CZ, CNOT -decompose_op(index) = index > 9 # T, T_Dagger, RX, RY, RZ - -""" -Destructively convert this to a Python adjacency list -""" -function python_adjlist!(adj) - pylist([pylist(adj[i] .- 1) for i = 1:length(adj)]) -end diff --git a/src/benchq/conversions/__init__.py b/src/benchq/conversions/__init__.py index 248a4f4d..e7645966 100644 --- a/src/benchq/conversions/__init__.py +++ b/src/benchq/conversions/__init__.py @@ -3,3 +3,4 @@ ################################################################################ from ._circuit_translations import SUPPORTED_CIRCUITS, export_circuit, import_circuit from ._openfermion_pyliqtr import openfermion_to_pyliqtr, pyliqtr_to_openfermion +from ._operator_translations import SUPPORTED_OPERATORS, get_pyliqtr_operator diff --git a/src/benchq/conversions/_openfermion_pyliqtr.py b/src/benchq/conversions/_openfermion_pyliqtr.py index e03ccf66..accbe7fa 100644 --- a/src/benchq/conversions/_openfermion_pyliqtr.py +++ b/src/benchq/conversions/_openfermion_pyliqtr.py @@ -1,7 +1,9 @@ ################################################################################ # © Copyright 2022 Zapata Computing Inc. ################################################################################ -from openfermion import QubitOperator, count_qubits +from typing import Union + +from openfermion import IsingOperator, QubitOperator, count_qubits from pyLIQTR.QSP.Hamiltonian import Hamiltonian @@ -18,7 +20,9 @@ def pyliqtr_to_openfermion(hamiltonian: Hamiltonian) -> QubitOperator: return qubit_op -def openfermion_to_pyliqtr(qubit_operator: QubitOperator) -> Hamiltonian: +def openfermion_to_pyliqtr( + qubit_operator: Union[QubitOperator, IsingOperator] +) -> Hamiltonian: """Converts a QubitOperator from Openfermion into pyLIQTR Args: diff --git a/src/benchq/conversions/_operator_translations.py b/src/benchq/conversions/_operator_translations.py new file mode 100644 index 00000000..edfe063c --- /dev/null +++ b/src/benchq/conversions/_operator_translations.py @@ -0,0 +1,58 @@ +import warnings +from functools import singledispatch +from typing import Union + +with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + # Numpy throws deprecation warnings due to the scipy import + from openfermion import QubitOperator, IsingOperator, InteractionOperator + +from orquestra.integrations.cirq.conversions._openfermion_conversions import ( + to_openfermion, +) +from orquestra.quantum.operators import PauliSum, PauliTerm +from pyLIQTR.QSP.Hamiltonian import Hamiltonian + +from ._openfermion_pyliqtr import openfermion_to_pyliqtr + +SUPPORTED_OPERATORS = Union[ + PauliTerm, PauliSum, QubitOperator, IsingOperator, Hamiltonian, InteractionOperator +] + + +@singledispatch +def get_pyliqtr_operator(hamiltonian) -> Hamiltonian: + raise NotImplementedError(f"Operator of type {type(hamiltonian)} not supported") + + +@get_pyliqtr_operator.register +def _(hamiltonian: PauliSum) -> Hamiltonian: + return openfermion_to_pyliqtr(to_openfermion(hamiltonian)) + + +@get_pyliqtr_operator.register +def _(hamiltonian: PauliTerm) -> Hamiltonian: + return openfermion_to_pyliqtr(to_openfermion(hamiltonian)) + + +@get_pyliqtr_operator.register +def _(hamiltonian: QubitOperator) -> Hamiltonian: + return openfermion_to_pyliqtr(hamiltonian) + + +@get_pyliqtr_operator.register +def _(hamiltonian: IsingOperator) -> Hamiltonian: + return openfermion_to_pyliqtr(hamiltonian) + + +@get_pyliqtr_operator.register +def _(hamiltonian: InteractionOperator) -> Hamiltonian: + raise NotImplementedError( + "Method for converting InteractionOperator to Hamiltonian is unspecified. " + "Please convert using Jordan-Wigner or Bravyi-Kitaev transformations." + ) + + +@get_pyliqtr_operator.register +def _(hamiltonian: Hamiltonian) -> Hamiltonian: + return hamiltonian diff --git a/src/benchq/decoder_modeling/decoder_resource_estimator.py b/src/benchq/decoder_modeling/decoder_resource_estimator.py index a7164b95..64bb07f4 100644 --- a/src/benchq/decoder_modeling/decoder_resource_estimator.py +++ b/src/benchq/decoder_modeling/decoder_resource_estimator.py @@ -12,7 +12,7 @@ def get_decoder_info( hw_model, decoder_model: Optional[DecoderModel], code_distance: int, - space_time_volume: float, + space_time_volume_in_logical_qubit_tocks: float, n_logical_qubits: int, ) -> Optional[DecoderInfo]: if not decoder_model: @@ -21,8 +21,8 @@ def get_decoder_info( speed_limit = get_decoder_distance_limit_due_to_speed(hw_model, decoder_model) if code_distance >= decoder_model.highest_calculated_distance: warnings.warn( - f"Code distance {code_distance} is too high to get resource estimates " - "because resource estimates have not been calculated for " + f"Code distance {code_distance} is too high to get decoder resource " + "estimates because decoder properties have not been calculated for " f"distances beyond {decoder_model.highest_calculated_distance}.", RuntimeWarning, ) @@ -36,7 +36,7 @@ def get_decoder_info( return None else: decoder_total_energy_in_joules = ( - space_time_volume + space_time_volume_in_logical_qubit_tocks * decoder_model.power_in_nanowatts(code_distance) * decoder_model.delay_in_nanoseconds(code_distance) * 1e-18 diff --git a/src/benchq/magic_state_distillation/autoccz_factories.py b/src/benchq/magic_state_distillation/autoccz_factories.py index 89216239..7b3066bb 100644 --- a/src/benchq/magic_state_distillation/autoccz_factories.py +++ b/src/benchq/magic_state_distillation/autoccz_factories.py @@ -29,7 +29,7 @@ def iter_auto_ccz_factories( space=(w, h), qubits=w * h * physical_qubits_per_logical_qubit(l2_distance), distillation_time_in_cycles=int(d * l2_distance), - n_t_gates_produced_per_distillation=2, + t_gates_per_distillation=2, ) @@ -102,7 +102,7 @@ def _two_level_t_state_factory_1p1000( space=(12 * 8, 4), qubits=(12 * 8) * (4) * physical_qubits_per_logical_qubit(31), distillation_time_in_cycles=6 * 31, - n_t_gates_produced_per_distillation=2, + t_gates_per_distillation=2, ) diff --git a/src/benchq/magic_state_distillation/litinski_factories.py b/src/benchq/magic_state_distillation/litinski_factories.py index 8b926ee7..b58956af 100644 --- a/src/benchq/magic_state_distillation/litinski_factories.py +++ b/src/benchq/magic_state_distillation/litinski_factories.py @@ -18,6 +18,7 @@ (387, 155), 43300, 130, + t_gates_per_distillation=4, ), MagicStateFactory( "(15-to-1)^4_13,5,5 x (20-to-4)_27,13,15", @@ -25,7 +26,7 @@ (382, 142), 46800, 157, - n_t_gates_produced_per_distillation=1, + t_gates_per_distillation=4, ), MagicStateFactory( "(15-to-1)^6_11,5,5 x (15-to-1)_25,11,11", @@ -59,7 +60,7 @@ (221, 96), 16400, 90.3, - n_t_gates_produced_per_distillation=4, + t_gates_per_distillation=4, ), MagicStateFactory( "(15-to-1)^4_9,3,3 x (15-to-1)_25,9,9", 6.3e-25, (193, 96), 18600, 67.8 diff --git a/src/benchq/magic_state_distillation/magic_state_factory.py b/src/benchq/magic_state_distillation/magic_state_factory.py index da2a4a7d..de628b03 100644 --- a/src/benchq/magic_state_distillation/magic_state_factory.py +++ b/src/benchq/magic_state_distillation/magic_state_factory.py @@ -9,4 +9,4 @@ class MagicStateFactory: space: Tuple[int, int] qubits: int distillation_time_in_cycles: float - n_t_gates_produced_per_distillation: int = 1 + t_gates_per_distillation: int = 1 # number of T-gates produced per distillation diff --git a/src/benchq/problem_embeddings/__init__.py b/src/benchq/problem_embeddings/__init__.py index 80d1d1f3..148c1617 100644 --- a/src/benchq/problem_embeddings/__init__.py +++ b/src/benchq/problem_embeddings/__init__.py @@ -1,6 +1,4 @@ ################################################################################ # © Copyright 2022-2023 Zapata Computing Inc. ################################################################################ -from ._trotter import get_trotter_circuit, get_trotter_program -from .qsp._qsp import get_qsp_circuit, get_qsp_program -from .quantum_program import QuantumProgram, get_program_from_circuit +from .quantum_program import QuantumProgram diff --git a/src/benchq/problem_embeddings/qaoa/__init__.py b/src/benchq/problem_embeddings/qaoa/__init__.py new file mode 100644 index 00000000..20592948 --- /dev/null +++ b/src/benchq/problem_embeddings/qaoa/__init__.py @@ -0,0 +1,4 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +from ._qaoa import get_qaoa_circuit, get_qaoa_program diff --git a/src/benchq/problem_embeddings/_qaoa.py b/src/benchq/problem_embeddings/qaoa/_qaoa.py similarity index 98% rename from src/benchq/problem_embeddings/_qaoa.py rename to src/benchq/problem_embeddings/qaoa/_qaoa.py index cef54426..29fd7461 100644 --- a/src/benchq/problem_embeddings/_qaoa.py +++ b/src/benchq/problem_embeddings/qaoa/_qaoa.py @@ -7,7 +7,7 @@ from orquestra.quantum.operators import PauliSum from orquestra.vqa.algorithms.qaoa import QAOA -from .quantum_program import QuantumProgram +from ..quantum_program import QuantumProgram def get_qaoa_circuit(hamiltonian: PauliSum, n_layers: int = 1) -> Circuit: diff --git a/src/benchq/problem_embeddings/qpe.py b/src/benchq/problem_embeddings/qpe.py index 3a29b544..a9b672c7 100644 --- a/src/benchq/problem_embeddings/qpe.py +++ b/src/benchq/problem_embeddings/qpe.py @@ -2,6 +2,7 @@ # © Copyright 2023 Zapata Computing Inc. ################################################################################ +from math import ceil from typing import Tuple import numpy as np @@ -58,7 +59,7 @@ def get_single_factorized_qpe_toffoli_and_qubit_cost( lam, allowable_phase_estimation_error, L=rank, - chi=bits_precision_coefficients, + chi=ceil(bits_precision_coefficients), stps=20000, )[0] @@ -67,7 +68,7 @@ def get_single_factorized_qpe_toffoli_and_qubit_cost( lam, allowable_phase_estimation_error, L=rank, - chi=bits_precision_coefficients, + chi=ceil(bits_precision_coefficients), stps=stps1, ) return sf_total_toffoli_cost, sf_logical_qubits diff --git a/src/benchq/problem_embeddings/qsp/__init__.py b/src/benchq/problem_embeddings/qsp/__init__.py index e69de29b..461542fa 100644 --- a/src/benchq/problem_embeddings/qsp/__init__.py +++ b/src/benchq/problem_embeddings/qsp/__init__.py @@ -0,0 +1,5 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +from ._lin_and_dong_qsp import get_lin_and_dong_qsp_circuit +from ._qsp import get_qsp_circuit, get_qsp_program diff --git a/src/benchq/problem_embeddings/qsp/_lin_and_dong_qsp.py b/src/benchq/problem_embeddings/qsp/_lin_and_dong_qsp.py index 98059a6f..b963b7dc 100644 --- a/src/benchq/problem_embeddings/qsp/_lin_and_dong_qsp.py +++ b/src/benchq/problem_embeddings/qsp/_lin_and_dong_qsp.py @@ -75,7 +75,7 @@ def build_control_rotation(num_qubits: int, phi: float) -> QuantumCircuit: return qc_crot -def build_qsp_circuit( +def get_lin_and_dong_qsp_circuit( num_qubits: int, be_qc: QuantumCircuit, phi_seq: npt.NDArray[np.float64], diff --git a/src/benchq/problem_embeddings/qsp/_qsp.py b/src/benchq/problem_embeddings/qsp/_qsp.py index 3c49e415..682f7f8d 100644 --- a/src/benchq/problem_embeddings/qsp/_qsp.py +++ b/src/benchq/problem_embeddings/qsp/_qsp.py @@ -7,13 +7,12 @@ import cirq import numpy as np import pyLIQTR.QSP as QSP -from orquestra.integrations.cirq.conversions import import_from_cirq, to_openfermion +from orquestra.integrations.cirq.conversions import import_from_cirq from orquestra.quantum.circuits import Circuit, GateOperation -from orquestra.quantum.operators import PauliRepresentation from pyLIQTR.QSP import gen_qsp from pyLIQTR.QSP.qsp_helpers import qsp_decompose_once -from ...conversions import openfermion_to_pyliqtr +from ...conversions import SUPPORTED_OPERATORS, get_pyliqtr_operator from ..quantum_program import QuantumProgram TCircuit = TypeVar("TCircuit") @@ -49,14 +48,14 @@ class _Indices: def get_qsp_circuit( - operator: PauliRepresentation, + operator: SUPPORTED_OPERATORS, required_precision: float, dt: float, tmax: float, sclf: float, use_random_angles: bool = False, ) -> Circuit: - pyliqtr_operator = openfermion_to_pyliqtr(to_openfermion(operator)) + pyliqtr_operator = get_pyliqtr_operator(operator) # Ns = int(np.ceil(tmax / dt)) # Total number of timesteps timestep_vec = np.arange(0, tmax + dt, sclf * dt) # Define array of timesteps @@ -95,11 +94,11 @@ def get_qsp_circuit( def get_qsp_program( - operator: PauliRepresentation, + operator: SUPPORTED_OPERATORS, n_block_encodings: int, - decompose_select_v: bool = True, + decompose_select_v: bool = False, ) -> QuantumProgram: - pyliqtr_operator = openfermion_to_pyliqtr(to_openfermion(operator)) + pyliqtr_operator = get_pyliqtr_operator(operator) angles = np.random.random(3) qsp_generator = QSP.QSP.QSP( diff --git a/src/benchq/problem_embeddings/quantum_program.py b/src/benchq/problem_embeddings/quantum_program.py index 7363cf00..f5e18926 100644 --- a/src/benchq/problem_embeddings/quantum_program.py +++ b/src/benchq/problem_embeddings/quantum_program.py @@ -1,9 +1,18 @@ ################################################################################ # © Copyright 2022-2023 Zapata Computing Inc. ################################################################################ -from typing import Callable, Sequence +import time +from copy import copy +from decimal import Decimal +from typing import Callable, List, Sequence -from orquestra.quantum.circuits import Circuit, GateOperation, ResetOperation +from orquestra.quantum.circuits import Circuit, GateOperation, I, ResetOperation + +from ..compilation.circuits import ( + compile_to_native_gates, + get_num_t_gates_per_rotation, + pyliqtr_transpile_to_clifford_t, +) class QuantumProgram: @@ -36,6 +45,12 @@ def __init__( self.steps = steps self.calculate_subroutine_sequence = calculate_subroutine_sequence + @staticmethod + def from_circuit(circuit: Circuit) -> "QuantumProgram": + return QuantumProgram( + [circuit], steps=1, calculate_subroutine_sequence=lambda x: [0] + ) + @property def multiplicities(self) -> Sequence[int]: mult_list = [0] * (max(self.subroutine_sequence) + 1) @@ -70,9 +85,11 @@ def n_t_gates(self) -> int: def min_n_nodes(self) -> int: return self.n_t_gates + self.n_rotation_gates + self.subroutines[0].n_qubits - def count_operations_in_subroutine(self, step: int, gates: Sequence[str]) -> int: + def count_operations_in_subroutine( + self, subroutine: int, gates: Sequence[str] + ) -> int: n_gates = 0 - for op in self.subroutines[step].operations: + for op in self.subroutines[subroutine].operations: if isinstance(op, GateOperation) and op.gate.name in gates: n_gates += 1 if isinstance(op, ResetOperation) and "ResetOperation" in gates: @@ -98,14 +115,98 @@ def replace_circuits(self, new_circuits: Sequence[Circuit]) -> "QuantumProgram": calculate_subroutine_sequence=self.calculate_subroutine_sequence, ) - @staticmethod - def from_circuit(circuit: Circuit) -> "QuantumProgram": + def transpile_to_clifford_t( + self, + transpilation_failure_tolerance: float, + ) -> "QuantumProgram": + tolerances = _distribute_transpilation_failure_tolerance_over_program( + self, transpilation_failure_tolerance + ) + circuits = [ + pyliqtr_transpile_to_clifford_t(circuit, circuit_precision=tolerance) + for circuit, tolerance in zip(self.subroutines, tolerances) + ] + return self.replace_circuits(circuits) + + def get_n_t_gates_after_transpilation(self, transpilation_failure_tolerance: float): + per_gate_synthesis_accuracy = 1 - ( + 1 - Decimal(transpilation_failure_tolerance) + ) ** Decimal(1 / self.n_rotation_gates) + + n_t_gates_per_rotation = get_num_t_gates_per_rotation( + per_gate_synthesis_accuracy + ) + + return self.n_t_gates + self.n_rotation_gates * n_t_gates_per_rotation + + def compile_to_native_gates(self, verbose: bool = False) -> "QuantumProgram": + if verbose: + print("Compiling to native gates...") + start = time.time() + circuits = [compile_to_native_gates(circuit) for circuit in self.subroutines] + if verbose: + print(f"Compiled in {time.time() - start} seconds.") + return self.replace_circuits(circuits) + + def combine_subroutines(self) -> "QuantumProgram": + new_circuit = Circuit() + for i in self.subroutine_sequence: + new_circuit += self.subroutines[i] return QuantumProgram( - [circuit], steps=1, calculate_subroutine_sequence=lambda x: [0] + [new_circuit], + steps=1, + calculate_subroutine_sequence=lambda x: [0], ) + def split_into_smaller_subroutines(self, max_size: int) -> "QuantumProgram": + max_size = int(max_size) + new_subroutines = [] + subroutine_splits: List[List[int]] = [[] for _ in range(len(self.subroutines))] + num_new_subroutines = 0 + n_qubits = self.subroutines[0].n_qubits + for i, sub in enumerate(self.subroutines): + if len(sub.operations) > max_size: + for j in range(0, len(sub.operations), max_size): + new_subroutines.append( + Circuit(sub._operations[j : j + max_size] + [I(n_qubits - 1)]) + ) + subroutine_splits[i].append( + len(self.subroutines) - 1 + num_new_subroutines + ) + num_new_subroutines += 1 + else: + new_subroutines.append(sub) + subroutine_splits[i] = [i] + + old_calculate_subroutine_sequence = copy(self.calculate_subroutine_sequence) + + def calculate_split_subroutine_sequence(steps: int) -> Sequence[int]: + new_sequence = [] + for i in old_calculate_subroutine_sequence(steps): + for j in subroutine_splits[i]: + new_sequence.append(j) + return new_sequence -def get_program_from_circuit(circuit: Circuit): - return QuantumProgram( - [circuit], steps=1, calculate_subroutine_sequence=lambda x: [0] + return QuantumProgram( + new_subroutines, + steps=self.steps, + calculate_subroutine_sequence=calculate_split_subroutine_sequence, + ) + + +def _distribute_transpilation_failure_tolerance_over_program( + program: QuantumProgram, total_transpilation_failure_tolerance: float +) -> Sequence[float]: + n_rots_per_subroutine = [ + program.count_operations_in_subroutine(i, ["RX", "RY", "RZ"]) + for i in range(len(program.subroutines)) + ] + + return ( + [0 for _ in program.subroutines] + if program.n_rotation_gates == 0 + else [ + total_transpilation_failure_tolerance * count / program.n_rotation_gates + for count in n_rots_per_subroutine + ] ) diff --git a/src/benchq/problem_embeddings/time_marching/_time_marching.py b/src/benchq/problem_embeddings/time_marching/_time_marching.py index 045a6412..d04232ee 100644 --- a/src/benchq/problem_embeddings/time_marching/_time_marching.py +++ b/src/benchq/problem_embeddings/time_marching/_time_marching.py @@ -15,7 +15,7 @@ from orquestra.quantum.circuits import PHASE, RZ, SX, Circuit, X from qiskit import QuantumCircuit, transpile -from ..qsp._lin_and_dong_qsp import build_qsp_circuit +from ..qsp._lin_and_dong_qsp import get_lin_and_dong_qsp_circuit from ..quantum_program import QuantumProgram from .compression_gadget import get_add_dagger, get_add_l from .matrix_properties import get_degree, get_kappa, get_num_of_grid_points @@ -151,7 +151,9 @@ def inverse_block_encoding( # Construct QSP circuit in Qiskit qsp_qubits = sel.n_qubits + 1 qiskit_sel = export_to_qiskit(sel) - sel_inverse = build_qsp_circuit(qsp_qubits, qiskit_sel, phi_seq, realpart=True) + sel_inverse = get_lin_and_dong_qsp_circuit( + qsp_qubits, qiskit_sel, phi_seq, realpart=True + ) return import_from_qiskit(sel_inverse) @@ -291,7 +293,7 @@ def get_time_marching_program( ) qsp_qubits = single_time_step.n_qubits + 1 amplified_single_time_step = import_from_qiskit( - build_qsp_circuit( + get_lin_and_dong_qsp_circuit( qsp_qubits, export_to_qiskit(single_time_step), phases, realpart=True ) ) diff --git a/src/benchq/problem_embeddings/trotter/__init__.py b/src/benchq/problem_embeddings/trotter/__init__.py new file mode 100644 index 00000000..b74c7788 --- /dev/null +++ b/src/benchq/problem_embeddings/trotter/__init__.py @@ -0,0 +1,4 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +from ._trotter import get_trotter_circuit, get_trotter_program diff --git a/src/benchq/problem_embeddings/_trotter.py b/src/benchq/problem_embeddings/trotter/_trotter.py similarity index 96% rename from src/benchq/problem_embeddings/_trotter.py rename to src/benchq/problem_embeddings/trotter/_trotter.py index 17a5e842..d330a07e 100644 --- a/src/benchq/problem_embeddings/_trotter.py +++ b/src/benchq/problem_embeddings/trotter/_trotter.py @@ -6,7 +6,7 @@ from orquestra.quantum.evolution import time_evolution from orquestra.quantum.operators._pauli_operators import PauliRepresentation -from .quantum_program import QuantumProgram +from ..quantum_program import QuantumProgram def get_trotter_circuit(hamiltonian, evolution_time, number_of_steps): diff --git a/src/benchq/resource_estimators/azure_estimator.py b/src/benchq/resource_estimators/azure_estimator.py index bfa5ee01..e8d76abb 100644 --- a/src/benchq/resource_estimators/azure_estimator.py +++ b/src/benchq/resource_estimators/azure_estimator.py @@ -18,15 +18,15 @@ def _azure_result_to_resource_info(job_results: dict) -> AzureResourceInfo: return AzureResourceInfo( n_physical_qubits=job_results["physicalCounts"]["physicalQubits"], - n_logical_qubits=job_results["physicalCounts"]["breakdown"][ - "algorithmicLogicalQubits" - ], total_time_in_seconds=job_results["physicalCounts"]["runtime_in_s"], + optimization="Space", code_distance=job_results["logicalQubit"]["codeDistance"], logical_error_rate=job_results["errorBudget"]["logical"], + n_logical_qubits=job_results["physicalCounts"]["breakdown"][ + "algorithmicLogicalQubits" + ], decoder_info=None, magic_state_factory_name="default", - routing_to_measurement_volume_ratio=0, extra=AzureExtra( cycle_time=job_results["logicalQubit"]["logicalCycleTime"], depth=job_results["physicalCounts"]["breakdown"]["algorithmicLogicalDepth"], @@ -35,7 +35,11 @@ def _azure_result_to_resource_info(job_results: dict) -> AzureResourceInfo: ) -class AzureResourceEstimator: +def azure_estimator( + algorithm: AlgorithmImplementation, + hw_model: Optional[BasicArchitectureModel] = None, + use_full_circuit: bool = True, +) -> AzureResourceInfo: """Class that interfaces between Bench-Q and Azure QRE. It allows to use Azure QRE to estimate the resources required to run @@ -51,76 +55,65 @@ class AzureResourceEstimator: Defaults to True. """ + if hw_model is not None: + warnings.warn( + "Supplying hardware model to AzureResourceEstimator is currently broken." + ) + azure_error_budget: Dict[str, float] = {} + if algorithm.error_budget is not None: + azure_error_budget = {} + azure_error_budget[ + "rotations" + ] = algorithm.error_budget.transpilation_failure_tolerance + remaining_error = algorithm.error_budget.hardware_failure_tolerance + azure_error_budget["logical"] = remaining_error / 2 + azure_error_budget["tstates"] = remaining_error / 2 + if use_full_circuit: + circuit = algorithm.program.full_circuit + return _estimate_resources_for_circuit(hw_model, circuit, azure_error_budget) + else: + raise NotImplementedError( + "Resource estimation for Quantum Programs which are not consisting " + "of a single circuit is not implemented yet." + ) - def __init__( - self, - hw_model: Optional[BasicArchitectureModel] = None, - use_full_circuit: bool = True, - ): - if hw_model is not None: - warnings.warn( - "Supplying hardware model to AzureResourceEstimator is " - "currently broken." - ) - self.hw_model = hw_model - self.use_full_circuit = use_full_circuit - - def estimate( - self, - algorithm: AlgorithmImplementation, - ) -> AzureResourceInfo: - azure_error_budget: Dict[str, float] = {} - if algorithm.error_budget is not None: - azure_error_budget = {} - azure_error_budget[ - "rotations" - ] = algorithm.error_budget.transpilation_failure_tolerance - remaining_error = algorithm.error_budget.hardware_failure_tolerance - azure_error_budget["logical"] = remaining_error / 2 - azure_error_budget["tstates"] = remaining_error / 2 - if self.use_full_circuit: - circuit = algorithm.program.full_circuit - return self._estimate_resources_for_circuit(circuit, azure_error_budget) - else: - raise NotImplementedError( - "Resource estimation for Quantum Programs which are not consisting " - "of a single circuit is not implemented yet." - ) - def _estimate_resources_for_circuit( - self, circuit: Circuit, error_budget: Dict[str, float] - ) -> AzureResourceInfo: - if self.hw_model is not None: - gate_time = self.hw_model.surface_code_cycle_time_in_seconds - gate_time_string = f"{int(gate_time * 1e9)} ns" - qubitParams = { - "name": "custom gate-based", - "instructionSet": "GateBased", - "oneQubitGateTime": gate_time_string, - # "oneQubitMeasurementTime": "30 μs", - "oneQubitGateErrorRate": (self.hw_model.physical_qubit_error_rate), - # "tStateErrorRate": 1e-3 - } - else: - qubitParams = None +def _estimate_resources_for_circuit( + hw_model: Optional[BasicArchitectureModel], + circuit: Circuit, + error_budget: Dict[str, float], +) -> AzureResourceInfo: + if hw_model is not None: + gate_time = hw_model.surface_code_cycle_time_in_seconds + gate_time_string = f"{int(gate_time * 1e9)} ns" + qubitParams = { + "name": "custom gate-based", + "instructionSet": "GateBased", + "oneQubitGateTime": gate_time_string, + # "oneQubitMeasurementTime": "30 μs", + "oneQubitGateErrorRate": (hw_model.physical_qubit_error_rate), + # "tStateErrorRate": 1e-3 + } + else: + qubitParams = None + + qiskit_circuit = export_to_qiskit(circuit) + provider = AzureQuantumProvider( + resource_id=os.getenv("AZURE_RESOURCE_ID"), location="East US" + ) - qiskit_circuit = export_to_qiskit(circuit) - provider = AzureQuantumProvider( - resource_id=os.getenv("AZURE_RESOURCE_ID"), location="East US" + backend = provider.get_backend("microsoft.estimator") + if qubitParams is None: + job = backend.run(qiskit_circuit, errorBudget=error_budget) + else: + job = backend.run( + qiskit_circuit, qubitParams=qubitParams, errorBudget=error_budget ) - backend = provider.get_backend("microsoft.estimator") - if qubitParams is None: - job = backend.run(qiskit_circuit, errorBudget=error_budget) - else: - job = backend.run( - qiskit_circuit, qubitParams=qubitParams, errorBudget=error_budget - ) - - job_monitor(job) - job_results = job.result().data() - del job_results["reportData"] - job_results["physicalCounts"]["runtime_in_s"] = ( - job_results["physicalCounts"]["runtime"] / 1e9 - ) - return _azure_result_to_resource_info(job_results) + job_monitor(job) + job_results = job.result().data() + del job_results["reportData"] + job_results["physicalCounts"]["runtime_in_s"] = ( + job_results["physicalCounts"]["runtime"] / 1e9 + ) + return _azure_result_to_resource_info(job_results) diff --git a/src/benchq/resource_estimators/default_estimators.py b/src/benchq/resource_estimators/default_estimators.py index 82d1ac68..c426e0ad 100644 --- a/src/benchq/resource_estimators/default_estimators.py +++ b/src/benchq/resource_estimators/default_estimators.py @@ -1,28 +1,22 @@ +import warnings from functools import partial -from typing import List, Optional +from typing import Optional import numpy as np from ..algorithms.data_structures import AlgorithmImplementation -from ..compilation import get_algorithmic_graph_from_ruby_slippers +from ..compilation.circuits.pyliqtr_transpilation import SYNTHESIS_SCALING +from ..compilation.graph_states import get_implementation_compiler from ..decoder_modeling import DecoderModel from ..problem_embeddings.quantum_program import QuantumProgram from ..quantum_hardware_modeling.hardware_architecture_models import ( BasicArchitectureModel, + IONTrapModel, + SCModel, ) -from .footprint_estimators.openfermion_estimator import footprint_estimator -from .graph_estimators.customizable_pipelines import ( - get_custom_extrapolated_estimate, - get_custom_resource_estimation, -) -from .graph_estimators.extrapolation_estimator import ExtrapolationResourceEstimator -from .graph_estimators.graph_estimator import GraphResourceEstimator -from .graph_estimators.transformers import ( - create_big_graph_from_subcircuits, - synthesize_clifford_t, - transpile_to_native_gates, -) -from .resource_info import ExtrapolatedGraphResourceInfo, ResourceInfo +from .graph_estimator import GraphResourceEstimator +from .openfermion_estimator import openfermion_estimator +from .resource_info import ResourceInfo DEFAULT_STEPS_TO_EXTRAPOLATE_FROM = [1, 2, 3] @@ -30,6 +24,7 @@ def get_precise_graph_estimate( algorithm_implementation: AlgorithmImplementation, hardware_model: BasicArchitectureModel, + optimization: str, decoder_model: Optional[DecoderModel] = None, ) -> ResourceInfo: """Run a slow resource estimate with the lowest amount of resources. @@ -51,22 +46,25 @@ def get_precise_graph_estimate( Returns: ResourceInfo: The resources required to run the algorithm. """ - estimator = GraphResourceEstimator(hardware_model, decoder_model=decoder_model) + algorithm_implementation = algorithm_implementation.transpile_to_clifford_t() + algorithm_implementation = AlgorithmImplementation.from_circuit( + algorithm_implementation.program.full_circuit, + algorithm_implementation.error_budget, + algorithm_implementation.n_shots, + ) - return get_custom_resource_estimation( + return GraphResourceEstimator(optimization).compile_and_estimate( algorithm_implementation, - estimator, - transformers=[ - transpile_to_native_gates, - synthesize_clifford_t(algorithm_implementation.error_budget), - create_big_graph_from_subcircuits(), - ], + get_implementation_compiler(), + hardware_model, + decoder_model=decoder_model, ) def get_fast_graph_estimate( algorithm_implementation: AlgorithmImplementation, hardware_model: BasicArchitectureModel, + optimization: str, decoder_model: Optional[DecoderModel] = None, ) -> ResourceInfo: """Run a slow resource estimate that's faster than the precise one. @@ -89,27 +87,26 @@ def get_fast_graph_estimate( Returns: ResourceInfo: The resources required to run the algorithm. """ - estimator = GraphResourceEstimator(hardware_model, decoder_model=decoder_model) + algorithm_implementation = AlgorithmImplementation.from_circuit( + algorithm_implementation.program.full_circuit, + algorithm_implementation.error_budget, + algorithm_implementation.n_shots, + ) - return get_custom_resource_estimation( + return GraphResourceEstimator(optimization).compile_and_estimate( algorithm_implementation, - estimator, - transformers=[ - transpile_to_native_gates, - create_big_graph_from_subcircuits( - graph_production_method=get_algorithmic_graph_from_ruby_slippers, - ), - ], + get_implementation_compiler(), + hardware_model, + decoder_model=decoder_model, ) -def get_precise_extrapolation_estimate( +def get_precise_stitched_estimate( algorithm_implementation: AlgorithmImplementation, hardware_model: BasicArchitectureModel, - steps_to_extrapolate_from: List[int], + optimization: str, decoder_model: Optional[DecoderModel] = None, - n_measurement_steps_fit_type: str = "logarithmic", -) -> ExtrapolatedGraphResourceInfo: +) -> ResourceInfo: """Run a faster resource estimate that's based on extrapolating from smaller circuits. @@ -129,31 +126,22 @@ def get_precise_extrapolation_estimate( Returns: ResourceInfo: The resources required to run the algorithm. """ - estimator = ExtrapolationResourceEstimator( - hardware_model, - steps_to_extrapolate_from, - decoder_model=decoder_model, - n_measurement_steps_fit_type=n_measurement_steps_fit_type, - ) + algorithm_implementation = algorithm_implementation.transpile_to_clifford_t() - return get_custom_extrapolated_estimate( + return GraphResourceEstimator(optimization).compile_and_estimate( algorithm_implementation, - estimator, - transformers=[ - transpile_to_native_gates, - synthesize_clifford_t(algorithm_implementation.error_budget), - create_big_graph_from_subcircuits(), - ], + get_implementation_compiler(), + hardware_model, + decoder_model=decoder_model, ) -def get_fast_extrapolation_estimate( +def get_fast_stitched_estimate( algorithm_implementation: AlgorithmImplementation, hardware_model: BasicArchitectureModel, - steps_to_extrapolate_from: List[int], + optimization: str, decoder_model: Optional[DecoderModel] = None, - n_measurement_steps_fit_type: str = "logarithmic", -) -> ExtrapolatedGraphResourceInfo: +) -> ResourceInfo: """The fastest resource estimate method, but also the least accurate one. Run a resource estimate by creating a part graph created by of the full @@ -173,49 +161,35 @@ def get_fast_extrapolation_estimate( Returns: ResourceInfo: The resources required to run the algorithm. """ - estimator = ExtrapolationResourceEstimator( + return GraphResourceEstimator(optimization).compile_and_estimate( + algorithm_implementation, + get_implementation_compiler(), hardware_model, - steps_to_extrapolate_from, decoder_model=decoder_model, - n_measurement_steps_fit_type=n_measurement_steps_fit_type, - ) - - return get_custom_extrapolated_estimate( - algorithm_implementation, - estimator, - transformers=[ - transpile_to_native_gates, - create_big_graph_from_subcircuits( - graph_production_method=get_algorithmic_graph_from_ruby_slippers, - ), - ], ) def get_footprint_estimate( algorithm_implementation: AlgorithmImplementation, hardware_model: BasicArchitectureModel, + optimization: str, decoder_model: Optional[DecoderModel] = None, ): - dummy_estimator = GraphResourceEstimator( - hardware_model, decoder_model=decoder_model - ) - - algorithm_implementation.program = transpile_to_native_gates( - algorithm_implementation.program - ) + if optimization == "Space": + warnings.warn( + "Time optimization is not supported for footprint analysis. " + "Using Space optimization." + ) - total_t_gates = dummy_estimator.get_n_total_t_gates( - algorithm_implementation.program.n_t_gates, - algorithm_implementation.program.n_rotation_gates, - algorithm_implementation.error_budget.transpilation_failure_tolerance, + algorithm_implementation.program = ( + algorithm_implementation.program.compile_to_native_gates() ) - + total_t_gates = algorithm_implementation.n_t_gates_after_transpilation hardware_failure_tolerance = ( algorithm_implementation.error_budget.hardware_failure_tolerance ) - return footprint_estimator( + return openfermion_estimator( algorithm_implementation.program.num_data_qubits, num_t=total_t_gates, architecture_model=hardware_model, @@ -228,6 +202,7 @@ def automatic_resource_estimator( algorithm_implementation: AlgorithmImplementation, hardware_model: BasicArchitectureModel, decoder_model: Optional[DecoderModel] = None, + optimization: Optional[str] = None, ) -> ResourceInfo: """Pick the appropriate resource estimator based on the size of the program. @@ -259,6 +234,17 @@ def automatic_resource_estimator( assert isinstance(algorithm_implementation.program, QuantumProgram) initial_number_of_steps = algorithm_implementation.program.steps + if optimization is None: + if hardware_model == SCModel: + optimization = "Space" + elif hardware_model == IONTrapModel: + optimization = "Time" + else: + raise ValueError( + f"Hardware model {hardware_model} has no default optimization. " + "Please specify one manually." + ) + graph_size = estimate_full_graph_size(algorithm_implementation, False) reduced_graph_size = estimate_full_graph_size(algorithm_implementation, True) @@ -277,8 +263,7 @@ def automatic_resource_estimator( print("Using precise graph estimator") elif extrapolaed_graph_size < 1e7: pipeline = partial( - get_precise_extrapolation_estimate, - steps_to_extrapolate_from=DEFAULT_STEPS_TO_EXTRAPOLATE_FROM, + get_precise_stitched_estimate, ) print("Using precise extrapolation graph estimator") elif reduced_graph_size < 1e7: @@ -286,8 +271,7 @@ def automatic_resource_estimator( print("Using fast graph estimator") elif small_extrapolated_graph_size < 1e7: pipeline = partial( - get_fast_extrapolation_estimate, - steps_to_extrapolate_from=DEFAULT_STEPS_TO_EXTRAPOLATE_FROM, + get_fast_stitched_estimate, ) print("Using fast extrapolation graph estimator") else: @@ -297,6 +281,7 @@ def automatic_resource_estimator( return pipeline( algorithm_implementation, hardware_model, + optimization, decoder_model=decoder_model, ) @@ -312,7 +297,7 @@ def estimate_full_graph_size( if not delayed_gate_synthesis: graph_complexity += ( algorithm_implementation.program.n_rotation_gates - * GraphResourceEstimator.SYNTHESIS_SCALING + * SYNTHESIS_SCALING * np.log2( 1 / algorithm_implementation.error_budget.transpilation_failure_tolerance diff --git a/src/benchq/resource_estimators/footprint_estimators/__init__.py b/src/benchq/resource_estimators/footprint_estimators/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/benchq/resource_estimators/graph_estimator.py b/src/benchq/resource_estimators/graph_estimator.py new file mode 100644 index 00000000..662e13f0 --- /dev/null +++ b/src/benchq/resource_estimators/graph_estimator.py @@ -0,0 +1,516 @@ +import warnings +from decimal import Decimal, getcontext +from math import ceil +from typing import Iterable, Optional, Tuple + +from benchq.decoder_modeling.decoder_resource_estimator import get_decoder_info + +from ..algorithms.data_structures import AlgorithmImplementation +from ..compilation.circuits.pyliqtr_transpilation import get_num_t_gates_per_rotation +from ..compilation.graph_states.compiled_data_structures import ( + CompiledAlgorithmImplementation, + CompiledQuantumProgram, +) +from ..decoder_modeling import DecoderModel +from ..magic_state_distillation import MagicStateFactory, iter_litinski_factories +from ..quantum_hardware_modeling import ( + BasicArchitectureModel, + DetailedArchitectureModel, +) +from ..quantum_hardware_modeling.devitt_surface_code import ( + get_total_logical_failure_rate, + logical_cell_error_rate, + physical_qubits_per_logical_qubit, +) +from ..visualization_tools.resource_allocation import CycleAllocation, QubitAllocation +from .resource_info import GraphExtra, GraphResourceInfo + +INITIAL_SYNTHESIS_ACCURACY = 0.0001 + + +class GraphResourceEstimator: + """Estimates resources needed to run an algorithm using graph state compilation. + + ATTRIBUTES: + hw_model (BasicArchitectureModel): The hardware model to use for the estimate. + typically, one would choose between the BASIC_SC_ARCHITECTURE_MODEL and + BASIC_ION_TRAP_ARCHITECTURE_MODEL. + decoder_model (Optional[DecoderModel]): The decoder model used to estimate. + If None, no estimates on the number of decoder are provided. + optimization (str): The optimization to use for the estimate. Either estimate + the resources needed to run the algorithm in the shortest time possible + ("Time") or the resources needed to run the algorithm with the smallest + number of physical qubits ("Space"). + magic_state_factory_iterator (Optional[Iterable[MagicStateFactory]]: iterator + over all magic_state_factories. + to be used during estimation. If not provided (or passed None) + litinski_factory_iterator will select magic_state_factory based + on hw_model parameter. + """ + + def __init__( + self, + optimization: str = "Space", + verbose: bool = False, + ): + self.optimization = optimization + self.verbose = verbose + getcontext().prec = 100 # need some extra precision for this calculation + + def _minimize_code_distance( + self, + compiled_program: CompiledQuantumProgram, + hardware_failure_tolerance: float, + transpilation_failure_tolerance: float, + magic_state_factory: MagicStateFactory, + n_t_gates_per_rotation: int, + hw_model: BasicArchitectureModel, + min_d: int = 3, + max_d: int = 200, + ) -> int: + + distillation_error_rate = 1 - ( + 1 - Decimal(magic_state_factory.distilled_magic_state_error_rate) + ) ** Decimal( + compiled_program.get_n_t_gates_after_transpilation( + transpilation_failure_tolerance + ) + ) + + if distillation_error_rate > hardware_failure_tolerance: + return -1 + + for code_distance in range(min_d, max_d, 2): + qubit_allocation, time_allocation = self.get_qubit_and_time_allocation( + compiled_program, + magic_state_factory, + n_t_gates_per_rotation, + code_distance, + ) + num_logical_qubits = qubit_allocation.get_num_logical_qubits( + 2 * physical_qubits_per_logical_qubit(code_distance) + ) + num_cycles = time_allocation.total + st_volume_in_logical_qubit_tocks = ( + num_logical_qubits * num_cycles / code_distance + ) + + ec_error_rate_at_this_distance = Decimal( + get_total_logical_failure_rate( + hw_model, + st_volume_in_logical_qubit_tocks, + code_distance, + ) + ) + + this_hardware_failure_rate = float( + distillation_error_rate + + ec_error_rate_at_this_distance + + distillation_error_rate * ec_error_rate_at_this_distance + ) + + if this_hardware_failure_rate < hardware_failure_tolerance: + return code_distance + + return -1 + + def get_qubit_and_time_allocation( + self, + compiled_program: CompiledQuantumProgram, + magic_state_factory: MagicStateFactory, + n_t_gates_per_rotation: int, + code_distance: int, + ) -> Tuple[QubitAllocation, CycleAllocation]: + time_allocation_for_each_subroutine = [ + CycleAllocation() for _ in range(len(compiled_program.subroutines)) + ] + qubit_allocation = QubitAllocation() + + if self.optimization == "Space": + # Injection and entanglement use the same bus and data qubits + qubit_allocation.log( + 2 + * compiled_program.num_logical_qubits + * physical_qubits_per_logical_qubit(code_distance), + "entanglement", + "Tstate-to-Tgate", + ) + # Use only 1 magic state factory + qubit_allocation.log(magic_state_factory.qubits, "distillation") + for i, subroutine in enumerate(compiled_program.subroutines): + for layer in range(subroutine.num_layers): + num_t_states_in_this_layer = ( + n_t_gates_per_rotation * subroutine.rotations_per_layer[layer] + + subroutine.t_states_per_layer[layer] + ) + num_distillations_in_this_layer = ( + num_t_states_in_this_layer + / magic_state_factory.t_gates_per_distillation + ) + + # Paralellize the first distillation and graph state preparation + time_allocation_for_each_subroutine[i].log_parallelized( + ( + magic_state_factory.distillation_time_in_cycles, + subroutine.graph_creation_tocks_per_layer[layer] + * code_distance, + ), + ("distillation", "entanglement"), + ) + + if magic_state_factory.t_gates_per_distillation == 1: + time_allocation_for_each_subroutine[i].log( + max(num_distillations_in_this_layer - 1, 0) + * magic_state_factory.distillation_time_in_cycles, + "distillation", + ) + # 1 tock in needed to inject a T state. See the Fig. 2 in the + # paper magic state distillation: not as costly as you think. + time_allocation_for_each_subroutine[i].log( + num_distillations_in_this_layer * code_distance, + "Tstate-to-Tgate", + ) + else: + # inject each T state into bus to hold them + time_allocation_for_each_subroutine[i].log( + num_distillations_in_this_layer * code_distance, + "Tstate-to-Tgate", + ) + # injection from bus can be parallelized with distillation + time_allocation_for_each_subroutine[i].log_parallelized( + ( + max(num_distillations_in_this_layer - 1, 0) + * magic_state_factory.distillation_time_in_cycles, + max(num_distillations_in_this_layer - 1, 0) + * magic_state_factory.t_gates_per_distillation + * code_distance, + ), + ("distillation", "Tstate-to-Tgate"), + ) + # inject gates from the last distillation + time_allocation_for_each_subroutine[i].log( + magic_state_factory.t_gates_per_distillation + * code_distance, + "Tstate-to-Tgate", + ) + elif self.optimization == "Time": + if compiled_program.n_rotation_gates == 0: + # If there are no rotation gates, we can use a single factory + # for each logical qubit. + num_factories_per_data_qubit = 1 + tocks_for_enacting_cliffords_due_to_rotations = 0 + else: + # Assume that at each layer we need to distill as many T gates + # as are needed for performing rotations on each logical qubit. + num_factories_per_data_qubit = n_t_gates_per_rotation + tocks_for_enacting_cliffords_due_to_rotations = 2 + + num_factories_per_data_qubit = ceil( + num_factories_per_data_qubit + / magic_state_factory.t_gates_per_distillation + ) + + qubit_allocation.log( + compiled_program.num_logical_qubits + * num_factories_per_data_qubit + * magic_state_factory.qubits, + "distillation", + ) + + factory_width = magic_state_factory.space[1] + # extra factor of 2 for the width of the logical qubit + # comes from needing to expose rough an smooth boundaries. + logical_qubit_side_length = 2 * 2 ** (1 / 2) * code_distance + factory_width_in_logical_qubit_side_lengths = int( + ceil(factory_width / logical_qubit_side_length) + ) + # For each logical qubit, add enough factories to cover a single + # node which can represent a distillation or a rotation. + # Note that the logical qubits are twice as wide as they are tall + # so that a rough and a smooth boundary can both face the bus. + qubit_allocation.log( + 2 * physical_qubits_per_logical_qubit(code_distance) + # bus qubits which span factory sides but are not + # used to inject T states + * compiled_program.num_logical_qubits + * num_factories_per_data_qubit + * (factory_width_in_logical_qubit_side_lengths - 1), + "entanglement", + ) + qubit_allocation.log( + 2 * physical_qubits_per_logical_qubit(code_distance) + # bus qubits which span factory sides + * ( + compiled_program.num_logical_qubits * num_factories_per_data_qubit + # logical qubits for computation + + compiled_program.num_logical_qubits + ), + "entanglement", + "Tstate-to-Tgate", + ) + + for i, subroutine in enumerate(compiled_program.subroutines): + for layer_num, layer in enumerate(range(subroutine.num_layers)): + + if layer_num > 0: + # we need to wait for the previous subroutine to finish + # measuring the qubits in the T basis before we continue + # with the next subroutine. However, we can distill T states + # and perform these measurements in parallel. We assume that + # it takes 1 cycle to measure these T states, which is a + # conservative assumption according to Fowler et al.'s + # seminal surface code paper: https://arxiv.org/abs/1208.0928 + # which puts measurement times at about 1/2 cycle time (see + # the middle of page 2). + time_allocation_for_each_subroutine[i].log_parallelized( + ( + num_factories_per_data_qubit, + num_factories_per_data_qubit, + ), + ("distillation", "Tstate-to-Tgate"), + ) + + if ( + num_factories_per_data_qubit + > magic_state_factory.distillation_time_in_cycles + and layer_num > 0 + ): + # cannot parallelize injection from previous layer + # and graph state preparation + time_allocation_for_each_subroutine[i].log( + num_factories_per_data_qubit + - magic_state_factory.distillation_time_in_cycles, + "Tstate-to-Tgate", + ) + time_allocation_for_each_subroutine[i].log( + ( + subroutine.graph_creation_tocks_per_layer[layer] + + tocks_for_enacting_cliffords_due_to_rotations + ) + * code_distance, + "entanglement", + ) + elif layer_num > 0: + # Distill T states and prepare graph state in parallel. + time_allocation_for_each_subroutine[i].log_parallelized( + ( + magic_state_factory.distillation_time_in_cycles + - num_factories_per_data_qubit, + ( + subroutine.graph_creation_tocks_per_layer[layer] + + tocks_for_enacting_cliffords_due_to_rotations + ) + * code_distance, + ), + ("distillation", "entanglement"), + ) + + # 1 tock to deliver T states to the synthilation qubits. + time_allocation_for_each_subroutine[i].log( + code_distance, "Tstate-to-Tgate" + ) + + else: + raise ValueError( + f"Unknown optimization: {self.optimization}. " + "Should be either 'Time' or 'Space'." + ) + + total_time_allocation = CycleAllocation() + for subroutine_index in compiled_program.subroutine_sequence: + total_time_allocation += time_allocation_for_each_subroutine[ + subroutine_index + ] + + return qubit_allocation, total_time_allocation + + def estimate_resources_from_compiled_implementation( + self, + compiled_implementation: CompiledAlgorithmImplementation, + hw_model: BasicArchitectureModel, + decoder_model: Optional[DecoderModel] = None, + magic_state_factory_iterator: Optional[Iterable[MagicStateFactory]] = None, + ) -> GraphResourceInfo: + magic_state_factory_iterator = iter( + magic_state_factory_iterator or iter_litinski_factories(hw_model) + ) + n_rotation_gates = compiled_implementation.program.n_rotation_gates + + this_transpilation_failure_tolerance = ( + compiled_implementation.error_budget.transpilation_failure_tolerance + ) + + # Search minimize the distance, magic state factories, and synthesis accuracy + # by looping over each until the smallest combination is found + while True: + magic_state_factory_found = False + for magic_state_factory in magic_state_factory_iterator: + if n_rotation_gates > 0: + per_gate_synthesis_accuracy = 1 - ( + 1 - Decimal(this_transpilation_failure_tolerance) + ) ** Decimal(1 / n_rotation_gates) + n_t_gates_per_rotation = get_num_t_gates_per_rotation( + per_gate_synthesis_accuracy + ) + else: + n_t_gates_per_rotation = 0 # no gates to synthesize + + code_distance = self._minimize_code_distance( + compiled_implementation.program, + compiled_implementation.error_budget.hardware_failure_tolerance, + this_transpilation_failure_tolerance, + magic_state_factory, + n_t_gates_per_rotation, + hw_model, + ) + + this_logical_cell_error_rate = logical_cell_error_rate( + hw_model.physical_qubit_error_rate, code_distance + ) + + if code_distance == -1: + continue + else: + magic_state_factory_found = True + break + + if not magic_state_factory_found: + warnings.warn( + "No viable magic_state_factory found! Returning null results.", + RuntimeWarning, + ) + return GraphResourceInfo( + total_time_in_seconds=0.0, + n_physical_qubits=-1, + optimization=self.optimization, + code_distance=-1, + logical_error_rate=1.0, + n_logical_qubits=-1, + magic_state_factory_name="No MagicStateFactory Found", + decoder_info=None, + extra=GraphExtra( + compiled_implementation, + None, + None, + ), + ) + if this_transpilation_failure_tolerance < this_logical_cell_error_rate: + # if the t gates typically do not come from rotation gates, then + # then you will have to restart the calculation from scratch. + if ( + compiled_implementation.program.n_t_gates + < 0.01 * compiled_implementation.program.n_rotation_gates + ): + raise RuntimeError( + "Run estimate again with lower synthesis failure tolerance." + ) + if this_transpilation_failure_tolerance < 1e-25: + warnings.warn( + "Synthesis tolerance low. Smaller problem size recommended.", + RuntimeWarning, + ) + this_transpilation_failure_tolerance /= 10 + else: + break + + # get error rate after correction + qubit_allocation, time_allocation = self.get_qubit_and_time_allocation( + compiled_implementation.program, + magic_state_factory, + n_t_gates_per_rotation, + code_distance, + ) + num_logical_qubits = qubit_allocation.get_num_logical_qubits( + 2 * physical_qubits_per_logical_qubit(code_distance) + ) + + num_cycles = time_allocation.total + + st_volume_in_logical_qubit_tocks = ( + num_logical_qubits * num_cycles / code_distance + ) + + total_logical_error_rate = get_total_logical_failure_rate( + hw_model, + st_volume_in_logical_qubit_tocks, + code_distance, + ) + + distillation_error_rate = float( + 1 + - (1 - Decimal(magic_state_factory.distilled_magic_state_error_rate)) + ** Decimal( + compiled_implementation.program.get_n_t_gates_after_transpilation( + this_transpilation_failure_tolerance + ) + ) + ) + + this_hardware_failure_rate = float( + distillation_error_rate + + total_logical_error_rate + + distillation_error_rate * total_logical_error_rate + ) + + # get time to get a single shot + time_per_circuit_in_seconds = ( + 6 * num_cycles * hw_model.surface_code_cycle_time_in_seconds + ) + + total_time_in_seconds = ( + time_per_circuit_in_seconds * compiled_implementation.n_shots + ) + + decoder_info = get_decoder_info( + hw_model, + decoder_model, + code_distance, + st_volume_in_logical_qubit_tocks, + num_logical_qubits, + ) + + resource_info = GraphResourceInfo( + total_time_in_seconds=total_time_in_seconds, + n_physical_qubits=qubit_allocation.total, + optimization=self.optimization, + code_distance=code_distance, + logical_error_rate=this_hardware_failure_rate, + # estimate the number of logical qubits using max node degree + n_logical_qubits=num_logical_qubits, + magic_state_factory_name=magic_state_factory.name, + decoder_info=decoder_info, + extra=GraphExtra( + compiled_implementation, + time_allocation, + qubit_allocation, + ), + ) + + resource_info.hardware_resource_info = ( + hw_model.get_hardware_resource_estimates(resource_info) + if isinstance(hw_model, DetailedArchitectureModel) + else None + ) + + return resource_info + + def compile_and_estimate( + self, + algorithm_implementation: AlgorithmImplementation, + algorithm_implementation_compiler, + hw_model: BasicArchitectureModel, + decoder_model: Optional[DecoderModel] = None, + magic_state_factory_iterator: Optional[Iterable[MagicStateFactory]] = None, + ): + compiled_implementation = algorithm_implementation_compiler( + algorithm_implementation, + self.optimization, + self.verbose, + ) + + return self.estimate_resources_from_compiled_implementation( + compiled_implementation, + hw_model, + decoder_model, + magic_state_factory_iterator, + ) diff --git a/src/benchq/resource_estimators/graph_estimators/__init__.py b/src/benchq/resource_estimators/graph_estimators/__init__.py deleted file mode 100644 index e702ef37..00000000 --- a/src/benchq/resource_estimators/graph_estimators/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -from .customizable_pipelines import ( - get_custom_extrapolated_estimate, - get_custom_resource_estimation, -) -from .extrapolation_estimator import ExtrapolationResourceEstimator -from .graph_estimator import GraphResourceEstimator, substrate_scheduler -from .transformers import ( - create_big_graph_from_subcircuits, - create_graphs_for_subcircuits, - remove_isolated_nodes, - synthesize_clifford_t, - transpile_to_native_gates, -) - -__all__ = [ - "get_custom_resource_estimation", - "get_custom_extrapolated_estimate", - "synthesize_clifford_t", - "transpile_to_native_gates", - "create_big_graph_from_subcircuits", - "create_graphs_for_subcircuits", - "GraphResourceEstimator", -] diff --git a/src/benchq/resource_estimators/graph_estimators/customizable_pipelines.py b/src/benchq/resource_estimators/graph_estimators/customizable_pipelines.py deleted file mode 100644 index f5c13d25..00000000 --- a/src/benchq/resource_estimators/graph_estimators/customizable_pipelines.py +++ /dev/null @@ -1,113 +0,0 @@ -from copy import deepcopy -from dataclasses import replace -from inspect import signature -from typing import List - -from ...algorithms.data_structures.algorithm_implementation import ( - AlgorithmImplementation, -) -from ...quantum_hardware_modeling.hardware_architecture_models import ( - BASIC_ION_TRAP_ARCHITECTURE_MODEL, -) -from ..resource_info import ExtrapolatedGraphData, ExtrapolatedGraphResourceInfo -from .extrapolation_estimator import ExtrapolationResourceEstimator -from .graph_estimator import GraphData, GraphPartition - - -def get_custom_resource_estimation( - algorithm_implementation: AlgorithmImplementation, - estimator, - transformers, -): - for transformer in transformers: - algorithm_implementation = replace( - algorithm_implementation, - program=transformer(algorithm_implementation.program), - ) - - return estimator.estimate(algorithm_implementation) - - -def _get_extrapolated_graph_data( - algorithm_implementation: AlgorithmImplementation, - estimator: ExtrapolationResourceEstimator, - transformers, -) -> ExtrapolatedGraphData: - synthesis_accuracy_for_each_rotation = 1 - ( - 1 - algorithm_implementation.error_budget.transpilation_failure_tolerance - ) ** (1 / algorithm_implementation.program.n_rotation_gates) - - small_programs_graph_data: List[GraphData] = [] - for i in estimator.steps_to_extrapolate_from: - print(f"Creating graph data for {i} steps...") - - # create copy of program for each number of steps - small_algorithm_implementation = deepcopy(algorithm_implementation) - small_algorithm_implementation.error_budget = replace( - algorithm_implementation.error_budget, - transpilation_failure_tolerance=synthesis_accuracy_for_each_rotation - * small_algorithm_implementation.program.n_rotation_gates, - ) - - for transformer in transformers: - small_algorithm_implementation.program.steps = i - small_algorithm_implementation.program = transformer( - small_algorithm_implementation.program - ) - - graph_data = estimator._get_graph_data_for_single_graph( - small_algorithm_implementation.program - ) - small_programs_graph_data.append(graph_data) - - # get transformers which are used before graph creation - circuit_transformers = [] - for transformer in transformers: - # This is a little hacky, would prefer to use a protocol here. - if signature(transformer).return_annotation is GraphPartition: - break - circuit_transformers.append(transformer) - - for transformer in circuit_transformers: - algorithm_implementation = replace( - algorithm_implementation, - program=transformer(algorithm_implementation.program), - ) - - return estimator.get_extrapolated_graph_data( - small_programs_graph_data, algorithm_implementation.program - ) - - -def get_extrapolated_graph_data( - algorithm_implementation: AlgorithmImplementation, - steps_to_extrapolate_from, - decoder_model, - transformers, -): - # the architecture model doesn't matter for extrapolating graph data - dummy_extrapolation_estimator = ExtrapolationResourceEstimator( - BASIC_ION_TRAP_ARCHITECTURE_MODEL, - steps_to_extrapolate_from, - decoder_model=decoder_model, - ) - return _get_extrapolated_graph_data( - algorithm_implementation, - estimator=dummy_extrapolation_estimator, - transformers=transformers, - ) - - -def get_custom_extrapolated_estimate( - algorithm_implementation: AlgorithmImplementation, - estimator: ExtrapolationResourceEstimator, - transformers, -) -> ExtrapolatedGraphResourceInfo: - extrapolated_graph_data = _get_extrapolated_graph_data( - algorithm_implementation, estimator, transformers - ) - - return estimator.estimate_given_extrapolation_data( - algorithm_implementation, - extrapolated_graph_data, - ) diff --git a/src/benchq/resource_estimators/graph_estimators/extrapolation_estimator.py b/src/benchq/resource_estimators/graph_estimators/extrapolation_estimator.py deleted file mode 100644 index b4e8065f..00000000 --- a/src/benchq/resource_estimators/graph_estimators/extrapolation_estimator.py +++ /dev/null @@ -1,227 +0,0 @@ -from dataclasses import replace -from math import ceil -from typing import Iterable, List, Optional - -import numpy as np -from scipy.optimize import minimize - -from ...algorithms.data_structures import AlgorithmImplementation -from ...decoder_modeling import DecoderModel -from ...magic_state_distillation import MagicStateFactory -from ...problem_embeddings.quantum_program import QuantumProgram -from ...quantum_hardware_modeling.hardware_architecture_models import ( - BasicArchitectureModel, -) -from ...resource_estimators.resource_info import ( - ExtrapolatedGraphData, - ExtrapolatedGraphResourceInfo, -) -from .graph_estimator import GraphData, GraphResourceEstimator - - -class ExtrapolationResourceEstimator(GraphResourceEstimator): - """Estimates resources needed to run an algorithm using graph state compilation - via extrapolating on the number of steps in the algorithm. - - ATTRIBUTES: - steps_to_extrapolate_from (List[int]): The number of steps to extrapolate from. - n_measurement_steps_fit_type (str): The type of fit to use for the number of - measurement steps. Either "logarithmic" or "linear". This heavily depends - on the circuit being analyzed. Defaults to "logarithmic". - max_graph_degree_fit_type (str): The type of fit to use for the maximum graph - degree. Either "logarithmic" or "linear". "logarithmic" is usually better - for larger circuits that hit the teleportation threshold for the ruby - slippers compiler. Defaults to "logarithmic". - """ - - def __init__( - self, - hw_model: BasicArchitectureModel, - steps_to_extrapolate_from: List[int], - decoder_model: Optional[DecoderModel] = None, - optimization: str = "space", - substrate_scheduler_preset: str = "fast", - magic_state_factory_iterator: Optional[Iterable[MagicStateFactory]] = None, - n_measurement_steps_fit_type: str = "logarithmic", - max_graph_degree_fit_type: str = "logarithmic", - ): - super().__init__( - hw_model, - decoder_model, - optimization, - substrate_scheduler_preset, - magic_state_factory_iterator, - ) - self.steps_to_extrapolate_from = steps_to_extrapolate_from - self.n_measurement_steps_fit_type = n_measurement_steps_fit_type - self.max_graph_degree_fit_type = max_graph_degree_fit_type - - def get_extrapolated_graph_data( - self, - data: List[GraphData], - program: QuantumProgram, - ) -> ExtrapolatedGraphData: - steps_to_extrapolate_to = program.steps - - # sometimes the n_measurement_steps is logarithmic, sometimes it's linear. - # we need to check which one is better by inspecting the fit - if self.max_graph_degree_fit_type == "logarithmic": - ( - max_graph_degree, - max_graph_degree_r_squared, - ) = _get_logarithmic_extrapolation( - self.steps_to_extrapolate_from, - np.array([d.max_graph_degree for d in data]), - steps_to_extrapolate_to, - ) - elif self.max_graph_degree_fit_type == "linear": - max_graph_degree, max_graph_degree_r_squared = _get_linear_extrapolation( - self.steps_to_extrapolate_from, - np.array([d.max_graph_degree for d in data]), - steps_to_extrapolate_to, - ) - else: - raise ValueError( - "max_graph_degree_fit_type must be either 'logarithmic' or 'linear'" - f", not {self.max_graph_degree_fit_type}" - ) - - n_nodes, n_nodes_r_squared = _get_linear_extrapolation( - self.steps_to_extrapolate_from, - np.array([d.n_nodes for d in data]), - steps_to_extrapolate_to, - ) - - # sometimes the n_measurement_steps is logarithmic, sometimes it's linear. - # we need to check which one is better by inspecting the fit - if self.n_measurement_steps_fit_type == "logarithmic": - ( - n_measurement_steps, - n_measurement_steps_r_squared, - ) = _get_logarithmic_extrapolation( - self.steps_to_extrapolate_from, - np.array([d.n_measurement_steps for d in data]), - steps_to_extrapolate_to, - ) - elif self.n_measurement_steps_fit_type == "linear": - ( - n_measurement_steps, - n_measurement_steps_r_squared, - ) = _get_linear_extrapolation( - self.steps_to_extrapolate_from, - np.array([d.n_measurement_steps for d in data]), - steps_to_extrapolate_to, - ) - else: - raise ValueError( - "n_measurement_steps_fit_type must be either 'logarithmic' or 'linear'" - f", not {self.n_measurement_steps_fit_type}" - ) - - return ExtrapolatedGraphData( - max_graph_degree=max_graph_degree, - n_measurement_steps=n_measurement_steps, - n_nodes=n_nodes, - n_t_gates=program.n_t_gates, - n_rotation_gates=program.n_rotation_gates, - n_logical_qubits_r_squared=max_graph_degree_r_squared, - n_measurement_steps_r_squared=n_measurement_steps_r_squared, - n_nodes_r_squared=n_nodes_r_squared, - data_used_to_extrapolate=data, - steps_to_extrapolate_to=steps_to_extrapolate_to, - ) - - def estimate_given_extrapolation_data( - self, - algorithm_implementation: AlgorithmImplementation, - extrapolated_info: ExtrapolatedGraphData, - ): - assert isinstance(algorithm_implementation.program, QuantumProgram) - resource_info = self.estimate_resources_from_graph_data( - extrapolated_info, algorithm_implementation - ) - - info = ExtrapolatedGraphResourceInfo( - n_logical_qubits=resource_info.n_logical_qubits, - extra=replace(extrapolated_info, n_nodes=resource_info.extra.n_nodes), - code_distance=resource_info.code_distance, - logical_error_rate=resource_info.logical_error_rate, - total_time_in_seconds=resource_info.total_time_in_seconds, - n_physical_qubits=resource_info.n_physical_qubits, - decoder_info=resource_info.decoder_info, - magic_state_factory_name=resource_info.magic_state_factory_name, - routing_to_measurement_volume_ratio=resource_info.routing_to_measurement_volume_ratio, # noqa - ) - return info - - -def _get_logarithmic_extrapolation(x, y, steps_to_extrapolate_to): - x = np.array(x) - y = np.array(y) - - def _logarithmic_objective(params): - a, b = params - y_pred = a * np.log(x) + b - error = y_pred - y - return np.sum(error**2) - - a_opt, b_opt = _extrapolate(x, y, steps_to_extrapolate_to, _logarithmic_objective) - - extrapolated_point = ceil(a_opt * np.log(steps_to_extrapolate_to) + b_opt) - - # Calculate R-squared value - y_mean = np.mean(y) - total_sum_of_squares = np.sum((y - y_mean) ** 2) - residual_sum_of_squares = np.sum((y - (a_opt * np.log(x) + b_opt)) ** 2) - - if total_sum_of_squares == 0: - r_squared = 1 - else: - r_squared = 1 - (residual_sum_of_squares / total_sum_of_squares) - - return extrapolated_point, r_squared - - -def _get_linear_extrapolation(x, y, steps_to_extrapolate_to): - x = np.array(x) - y = np.array(y) - - def _linear_objective(params): - a, b = params - y_pred = a * x + b - error = y_pred - y - return np.sum(error**2) - - a_opt, b_opt = _extrapolate(x, y, steps_to_extrapolate_to, _linear_objective) - - extrapolated_point = ceil(a_opt * steps_to_extrapolate_to + b_opt) - - # Calculate R-squared value - y_mean = np.mean(y) - total_sum_of_squares = np.sum((y - y_mean) ** 2) - residual_sum_of_squares = np.sum((y - (a_opt * x + b_opt)) ** 2) - - if total_sum_of_squares == 0: - r_squared = 1 - else: - r_squared = 1 - (residual_sum_of_squares / total_sum_of_squares) - - return extrapolated_point, r_squared - - -def _extrapolate(x, y, steps_to_extrapolate_to, objective): - # Define the constraint that the slope (a) must be greater than zero - def slope_constraint(params): - a, _ = params - return a - - # Perform the optimization - initial_guess = [1.0, 1.0] - bounds = [(0, None), (None, None)] - constraints = {"type": "ineq", "fun": slope_constraint} - result = minimize(objective, initial_guess, bounds=bounds, constraints=constraints) - - # Extrapolated to desired point - a_opt, b_opt = result.x - - return a_opt, b_opt diff --git a/src/benchq/resource_estimators/graph_estimators/graph_estimator.py b/src/benchq/resource_estimators/graph_estimators/graph_estimator.py deleted file mode 100644 index 84429fad..00000000 --- a/src/benchq/resource_estimators/graph_estimators/graph_estimator.py +++ /dev/null @@ -1,472 +0,0 @@ -import time -import warnings -from dataclasses import replace -from decimal import Decimal, getcontext -from math import ceil -from typing import Iterable, Optional - -import networkx as nx -from graph_state_generation.optimizers import ( - fast_maximal_independent_set_stabilizer_reduction, - greedy_stabilizer_measurement_scheduler, -) -from graph_state_generation.substrate_scheduler import TwoRowSubstrateScheduler - -from benchq.decoder_modeling.decoder_resource_estimator import get_decoder_info - -from ...algorithms.data_structures import AlgorithmImplementation -from ...algorithms.data_structures.graph_partition import GraphPartition -from ...decoder_modeling import DecoderModel -from ...magic_state_distillation import MagicStateFactory, iter_litinski_factories -from ...quantum_hardware_modeling import ( - BasicArchitectureModel, - DetailedArchitectureModel, -) -from ...quantum_hardware_modeling.devitt_surface_code import ( - get_total_logical_failure_rate, - logical_cell_error_rate, - physical_qubits_per_logical_qubit, -) -from ..resource_info import GraphData, GraphResourceInfo -from .transformers import remove_isolated_nodes_from_graph - -INITIAL_SYNTHESIS_ACCURACY = 0.0001 - - -def substrate_scheduler(graph: nx.Graph, preset: str) -> TwoRowSubstrateScheduler: - """A simple interface for running the substrate scheduler. Can be run quickly or - optimized for smaller runtime. Using the "optimized" preset can halve the number - of measurement steps, but takes about 100x longer to run. It's probably only - suitable for graphs with less than 10^5 nodes. - - Args: - graph (nx.Graph): Graph to create substrate schedule for. - preset (str): Can optimize for speed ("fast") or for smaller number of - measurement steps ("optimized"). - - Returns: - TwoRowSubstrateScheduler: A substrate scheduler object with the schedule - already created. - """ - cleaned_graph = remove_isolated_nodes_from_graph(graph)[1] - - print("starting substrate scheduler") - start = time.time() - if preset == "fast": - compiler = TwoRowSubstrateScheduler( - cleaned_graph, - stabilizer_scheduler=greedy_stabilizer_measurement_scheduler, - ) - elif preset == "optimized": - compiler = TwoRowSubstrateScheduler( - cleaned_graph, - pre_mapping_optimizer=fast_maximal_independent_set_stabilizer_reduction, - stabilizer_scheduler=greedy_stabilizer_measurement_scheduler, - ) - else: - raise ValueError( - f"Unknown preset: {preset}. Should be either 'fast' or 'optimized'." - ) - compiler.run() - end = time.time() - print("substrate scheduler took", end - start, "seconds") - return compiler - - -class GraphResourceEstimator: - """Estimates resources needed to run an algorithm using graph state compilation. - - ATTRIBUTES: - hw_model (BasicArchitectureModel): The hardware model to use for the estimate. - typically, one would choose between the BASIC_SC_ARCHITECTURE_MODEL and - BASIC_ION_TRAP_ARCHITECTURE_MODEL. - decoder_model (Optional[DecoderModel]): The decoder model used to estimate. - If None, no estimates on the number of decoder are provided. - optimization (str): The optimization to use for the estimate. Either estimate - the resources needed to run the algorithm in the shortest time possible - ("time") or the resources needed to run the algorithm with the smallest - number of physical qubits ("space"). - substrate_scheduler_preset (str): Optimize for speed ("fast") so that it can - be run on larger graphs or for lower resource estimates ("optimized"). For - graphs of sizes in the thousands of nodes or higher, "fast" is recommended. - magic_state_factory_iterator (Optional[Iterable[MagicStateFactory]]: iterator - over all magic_state_factories. - to be used during estimation. If not provided (or passed None) - litinski_factory_iterator will select magic_state_factory based - on hw_model parameter. - """ - - # Assumes gridsynth scaling - SYNTHESIS_SCALING = 4 - - def __init__( - self, - hw_model: BasicArchitectureModel, - decoder_model: Optional[DecoderModel] = None, - optimization: str = "space", - substrate_scheduler_preset: str = "fast", - magic_state_factory_iterator: Optional[Iterable[MagicStateFactory]] = None, - ): - self.hw_model = hw_model - self.decoder_model = decoder_model - self.optimization = optimization - self.substrate_scheduler_preset = substrate_scheduler_preset - getcontext().prec = 100 # need some extra precision for this calculation - self.magic_state_factory_iterator = ( - magic_state_factory_iterator or iter_litinski_factories(hw_model) - ) - - def _get_n_measurement_steps(self, graph) -> int: - compiler = substrate_scheduler(graph, self.substrate_scheduler_preset) - n_measurement_steps = len(compiler.measurement_steps) - return n_measurement_steps - - def _get_graph_data_for_single_graph(self, problem: GraphPartition) -> GraphData: - graph = problem.subgraphs[0] - print("getting max graph degree") - max_graph_degree = max(deg for _, deg in graph.degree()) - n_measurement_steps = self._get_n_measurement_steps(graph) - return GraphData( - max_graph_degree=max_graph_degree, - n_nodes=graph.number_of_nodes(), - n_t_gates=problem.n_t_gates, - n_rotation_gates=problem.n_rotation_gates, - n_measurement_steps=n_measurement_steps, - ) - - def _minimize_code_distance( - self, - n_total_t_gates: int, - graph_data: GraphData, - hardware_failure_tolerance: float, - magic_state_factory: MagicStateFactory, - min_d: int = 4, - max_d: int = 200, - ) -> int: - for code_distance in range(min_d, max_d): - logical_st_volume = self.get_logical_st_volume( - n_total_t_gates, graph_data, code_distance, magic_state_factory - ) - ec_error_rate_at_this_distance = get_total_logical_failure_rate( - self.hw_model, - logical_st_volume, - code_distance, - ) - - if ec_error_rate_at_this_distance < hardware_failure_tolerance: - return code_distance - - raise RuntimeError( - f"Required distance is greater than maximum allowable distance: {max_d}." - ) - - def _get_v_graph( - self, - graph_data: GraphData, - code_distance: int, - ): - if self.optimization == "space": - V_graph = ( - 2 - * graph_data.max_graph_degree - * graph_data.n_measurement_steps - * code_distance - ) - elif self.optimization == "time": - V_graph = ( - 2 * graph_data.n_nodes * graph_data.n_measurement_steps * code_distance - ) - else: - raise ValueError( - f"Unknown optimization: {self.optimization}. " - "Should be either 'time' or 'space'." - ) - return V_graph - - def _get_v_measure( - self, - n_total_t_gates: int, - graph_data: GraphData, - code_distance: int, - magic_state_factory: MagicStateFactory, - ): - if self.optimization == "space": - V_measure = ( - 2 - * graph_data.max_graph_degree - * n_total_t_gates - * (magic_state_factory.distillation_time_in_cycles + code_distance) - ) - elif self.optimization == "time": - V_measure = ( - n_total_t_gates - * magic_state_factory.space[1] - * (magic_state_factory.distillation_time_in_cycles + code_distance) - / (2 ** (1 / 2) * code_distance + 1) - ) - else: - raise ValueError( - f"Unknown optimization: {self.optimization}. " - "Should be either 'time' or 'space'." - ) - return V_measure - - def get_logical_st_volume( - self, - n_total_t_gates: int, - graph_data: GraphData, - code_distance: int, - magic_state_factory: MagicStateFactory, - ): - return self._get_v_graph(graph_data, code_distance) + self._get_v_measure( - n_total_t_gates, graph_data, code_distance, magic_state_factory - ) - - def get_n_total_t_gates( - self, - n_t_gates: int, - n_rotation_gates: int, - transpilation_failure_tolerance: float, - ) -> int: - if n_rotation_gates != 0: - per_gate_synthesis_accuracy = 1 - ( - 1 - Decimal(transpilation_failure_tolerance) - ) ** Decimal(1 / n_rotation_gates) - - n_t_gates_used_at_measurement = ( - n_rotation_gates - * self.SYNTHESIS_SCALING - * int((1 / per_gate_synthesis_accuracy).log10() / Decimal(2).log10()) - ) - else: - n_t_gates_used_at_measurement = 0 - - return n_t_gates + n_t_gates_used_at_measurement - - def _get_time_per_circuit_in_seconds( - self, - graph_data: GraphData, - code_distance: int, - n_total_t_gates: float, - magic_state_factory: MagicStateFactory, - ) -> float: - if self.optimization == "space": - return ( - 6 - * self.hw_model.surface_code_cycle_time_in_seconds - * ( - graph_data.n_measurement_steps * code_distance - + (magic_state_factory.distillation_time_in_cycles + code_distance) - * n_total_t_gates - ) - ) - elif self.optimization == "time": - return ( - 6 - * self.hw_model.surface_code_cycle_time_in_seconds - * ( - graph_data.n_measurement_steps * code_distance - + magic_state_factory.distillation_time_in_cycles - + code_distance - ) - ) - else: - raise NotImplementedError( - "Must use either time or space optimal estimator." - ) - - def _get_n_physical_qubits( - self, - graph_data: GraphData, - code_distance: int, - magic_state_factory: MagicStateFactory, - ) -> int: - patch_size = physical_qubits_per_logical_qubit(code_distance) - if self.optimization == "space": - return ( - 2 * graph_data.max_graph_degree * patch_size - + magic_state_factory.qubits - ) - elif self.optimization == "time": - return ceil( - graph_data.max_graph_degree * patch_size - + 2 ** (0.5) - * graph_data.n_measurement_steps - * magic_state_factory.space[0] - + magic_state_factory.qubits * graph_data.n_measurement_steps - ) - else: - raise NotImplementedError( - "Must use either time or space optimal estimator." - ) - - def estimate_resources_from_graph_data( - self, - graph_data: GraphData, - algorithm_implementation: AlgorithmImplementation, - ) -> GraphResourceInfo: - this_transpilation_failure_tolerance = ( - algorithm_implementation.error_budget.transpilation_failure_tolerance - ) - - magic_state_factory_iterator = iter(self.magic_state_factory_iterator) - - # Approximate the number of logical qubits for the bus architecture - # TODO: Update to accommodate the space vs time optimal compilation - # once we have the substrate scheduler properly implemented. - n_logical_qubits = 2 * graph_data.max_graph_degree - - while True: - magic_state_factory_found = False - for magic_state_factory in magic_state_factory_iterator: - tmp_graph_data = replace( - graph_data, - n_nodes=ceil( - graph_data.n_nodes - / magic_state_factory.n_t_gates_produced_per_distillation - ), - n_t_gates=ceil( - graph_data.n_t_gates - / magic_state_factory.n_t_gates_produced_per_distillation - ), - ) - - n_total_t_gates = self.get_n_total_t_gates( - tmp_graph_data.n_t_gates, - tmp_graph_data.n_rotation_gates, - this_transpilation_failure_tolerance, - ) - code_distance = self._minimize_code_distance( - n_total_t_gates, - tmp_graph_data, - algorithm_implementation.error_budget.hardware_failure_tolerance, - magic_state_factory, - ) - this_logical_cell_error_rate = logical_cell_error_rate( - self.hw_model.physical_qubit_error_rate, code_distance - ) - - # Ensure we can ignore errors from magic state distillation. - if ( - magic_state_factory.distilled_magic_state_error_rate - < this_logical_cell_error_rate - ): - magic_state_factory_found = True - break - if not magic_state_factory_found: - warnings.warn( - "No viable magic_state_factory found! Returning null results.", - RuntimeWarning, - ) - return GraphResourceInfo( - code_distance=-1, - logical_error_rate=1.0, - n_logical_qubits=n_logical_qubits, - total_time_in_seconds=0.0, - n_physical_qubits=0, - magic_state_factory_name="No MagicStateFactory Found", - decoder_info=None, - routing_to_measurement_volume_ratio=0.0, - extra=graph_data, - ) - if this_transpilation_failure_tolerance < this_logical_cell_error_rate: - # if the t gates typically do not come from rotation gates, then - # then you will have to restart the calculation from scratch. - if graph_data.n_t_gates < 0.01 * graph_data.n_nodes: - raise RuntimeError( - "Run estimate again with lower synthesis failure tolerance." - ) - if this_transpilation_failure_tolerance < 1e-10: - warnings.warn( - "Synthesis tolerance low. Smaller problem size recommended.", - RuntimeWarning, - ) - this_transpilation_failure_tolerance /= 10 - else: - graph_data = tmp_graph_data - break - - # get error rate after correction - space_time_volume = self.get_logical_st_volume( - n_total_t_gates, graph_data, code_distance, magic_state_factory - ) - - graph_measure_ratio = ( - self._get_v_graph(graph_data, code_distance) / space_time_volume - ) - - logical_st_volume = self.get_logical_st_volume( - n_total_t_gates, graph_data, code_distance, magic_state_factory - ) - - total_logical_error_rate = get_total_logical_failure_rate( - self.hw_model, - logical_st_volume, - code_distance, - ) - - # get number of physical qubits needed for the computation - n_physical_qubits = self._get_n_physical_qubits( - graph_data, code_distance, magic_state_factory - ) - - # get total time to run algorithm - time_per_circuit_in_seconds = self._get_time_per_circuit_in_seconds( - graph_data, code_distance, n_total_t_gates, magic_state_factory - ) - - # The total space time volume, prior to measurements is, - # V_{graph}= 2\Delta S (where we measure each of the steps, - # S in terms of tocks, corresponding to d cycle times. - # d will be solved for later). For each distilled T-state, - # C-cycles are needed to prepare the state and 1-Tock is required - # to interact the state with the graph node and measure it in - # the X or Z-basis. Hence for each node measurement (assuming - # T-basis measurements), the volume increases to, - # V = 2*Delta*S*d+ 2*Delta*(C+d). - - total_time_in_seconds = ( - time_per_circuit_in_seconds * algorithm_implementation.n_shots - ) - - decoder_info = get_decoder_info( - self.hw_model, - self.decoder_model, - code_distance, - space_time_volume, - n_logical_qubits, - ) - - return GraphResourceInfo( - code_distance=code_distance, - logical_error_rate=total_logical_error_rate, - n_logical_qubits=n_logical_qubits, - total_time_in_seconds=total_time_in_seconds, - n_physical_qubits=n_physical_qubits, - magic_state_factory_name=magic_state_factory.name, - decoder_info=decoder_info, - routing_to_measurement_volume_ratio=graph_measure_ratio, - extra=graph_data, - ) - - def estimate( - self, algorithm_implementation: AlgorithmImplementation - ) -> GraphResourceInfo: - assert isinstance(algorithm_implementation.program, GraphPartition) - if len(algorithm_implementation.program.subgraphs) == 1: - graph_data = self._get_graph_data_for_single_graph( - algorithm_implementation.program - ) - resource_info = self.estimate_resources_from_graph_data( - graph_data, algorithm_implementation - ) - if isinstance(self.hw_model, DetailedArchitectureModel): - resource_info.hardware_resource_info = ( - self.hw_model.get_hardware_resource_estimates(resource_info) - ) - return resource_info - else: - raise NotImplementedError( - "Resource estimation without combining subgraphs is not yet " - "supported." - ) diff --git a/src/benchq/resource_estimators/graph_estimators/transformers.py b/src/benchq/resource_estimators/graph_estimators/transformers.py deleted file mode 100644 index ae7a3a7a..00000000 --- a/src/benchq/resource_estimators/graph_estimators/transformers.py +++ /dev/null @@ -1,138 +0,0 @@ -import time -from copy import copy -from typing import Callable, Sequence, Tuple - -import networkx as nx - -from ...algorithms.data_structures import ErrorBudget, GraphPartition -from ...compilation import ( - get_algorithmic_graph_from_ruby_slippers, - pyliqtr_transpile_to_clifford_t, -) -from ...compilation import transpile_to_native_gates as _transpile_to_native_gates -from ...problem_embeddings.quantum_program import ( - QuantumProgram, - get_program_from_circuit, -) - - -def _distribute_transpilation_failure_tolerance( - program: QuantumProgram, total_transpilation_failure_tolerance: float -) -> Sequence[float]: - n_rots_per_subroutine = [ - program.count_operations_in_subroutine(i, ["RX", "RY", "RZ"]) - for i in range(len(program.subroutines)) - ] - # Not using program n_rotation_gates because we already computed partial - # counts for subroutines. - n_total_rots = sum( - n_rotations * multi - for n_rotations, multi in zip(n_rots_per_subroutine, program.multiplicities) - ) - - return ( - [0 for _ in program.subroutines] - if n_total_rots == 0 - else [ - total_transpilation_failure_tolerance * count / n_total_rots - for count in n_rots_per_subroutine - ] - ) - - -def synthesize_clifford_t( - error_budget: ErrorBudget, -) -> Callable[[QuantumProgram], QuantumProgram]: - def _transformer(program: QuantumProgram) -> QuantumProgram: - tolerances = _distribute_transpilation_failure_tolerance( - program, error_budget.transpilation_failure_tolerance - ) - circuits = [ - pyliqtr_transpile_to_clifford_t(circuit, circuit_precision=tolerance) - for circuit, tolerance in zip(program.subroutines, tolerances) - ] - return program.replace_circuits(circuits) - - return _transformer - - -def transpile_to_native_gates(program: QuantumProgram) -> QuantumProgram: - print("Transpiling to native gates...") - start = time.time() - circuits = [_transpile_to_native_gates(circuit) for circuit in program.subroutines] - print(f"Transpiled in {time.time() - start} seconds.") - return QuantumProgram( - circuits, - steps=program.steps, - calculate_subroutine_sequence=program.calculate_subroutine_sequence, - ) - - -def create_graphs_for_subcircuits( - graph_production_method=get_algorithmic_graph_from_ruby_slippers, -) -> Callable[[QuantumProgram], GraphPartition]: - def _transformer(program: QuantumProgram) -> GraphPartition: - graphs_list = [ - graph_production_method(circuit) for circuit in program.subroutines - ] - return GraphPartition(program, graphs_list) - - return _transformer - - -def create_big_graph_from_subcircuits( - graph_production_method=get_algorithmic_graph_from_ruby_slippers, -) -> Callable[[QuantumProgram], GraphPartition]: - def _transformer(program: QuantumProgram) -> GraphPartition: - print("Creating big graph from subcircuits...") - big_circuit = program.full_circuit - new_program = get_program_from_circuit(big_circuit) - graph = graph_production_method(big_circuit) - return GraphPartition(new_program, [graph]) - - return _transformer - - -def remove_isolated_nodes(graph_partition: GraphPartition) -> GraphPartition: - """Sometimes our circuits can generate a lot of extra nodes because of how - RESET is implemented. This transformer removes these nodes from the - graph to prevent them from influencing the costing. There are 3 known sources - of isolated nodes: - 1. Unneeded resets at the beginning of the circuit. - 2. Decomposing rotations into gates sometimes gives bare nodes if a - T gate is placed after a reset. (most concerning) - 3. Consecutive reset gates happening later on in the circuit. - - Args: - graph_partition (GraphPartition): graph partition to remove the isoated - nodes of. - - Returns: - GraphPartition: input graph partition with isolated nodes removed. - """ - print("Removing isolated nodes from graph...") - start = time.time() - new_graphs = [] - total_nodes_removed = 0 - for graph in graph_partition.subgraphs: - n_nodes_removed, graph = remove_isolated_nodes_from_graph(graph) - - total_nodes_removed += n_nodes_removed - new_graphs.append(graph) - - print( - f"Removed {total_nodes_removed} isolated nodes " - f"in {time.time() - start} seconds." - ) - return GraphPartition(graph_partition.program, new_graphs) - - -def remove_isolated_nodes_from_graph(graph: nx.Graph) -> Tuple[int, nx.Graph]: - cleaned_graph = copy(graph) - isolated_nodes = list(nx.isolates(cleaned_graph)) - n_nodes_removed = len(isolated_nodes) - - cleaned_graph.remove_nodes_from(isolated_nodes) - cleaned_graph = nx.convert_node_labels_to_integers(cleaned_graph) - - return n_nodes_removed, cleaned_graph diff --git a/src/benchq/resource_estimators/footprint_estimators/openfermion_estimator.py b/src/benchq/resource_estimators/openfermion_estimator.py similarity index 93% rename from src/benchq/resource_estimators/footprint_estimators/openfermion_estimator.py rename to src/benchq/resource_estimators/openfermion_estimator.py index e841372b..b4d1c0ac 100644 --- a/src/benchq/resource_estimators/footprint_estimators/openfermion_estimator.py +++ b/src/benchq/resource_estimators/openfermion_estimator.py @@ -15,20 +15,20 @@ import dataclasses import math -from typing import Iterable, Optional +from typing import Iterable, Optional, Tuple -from ...decoder_modeling.decoder_resource_estimator import get_decoder_info -from ...magic_state_distillation import MagicStateFactory -from ...magic_state_distillation.autoccz_factories import iter_all_openfermion_factories -from ...quantum_hardware_modeling import ( +from ..decoder_modeling.decoder_resource_estimator import get_decoder_info +from ..magic_state_distillation import MagicStateFactory +from ..magic_state_distillation.autoccz_factories import iter_all_openfermion_factories +from ..quantum_hardware_modeling import ( BASIC_SC_ARCHITECTURE_MODEL, BasicArchitectureModel, ) -from ...quantum_hardware_modeling.fowler_surface_code import ( +from ..quantum_hardware_modeling.fowler_surface_code import ( logical_cell_error_rate, physical_qubits_per_logical_qubit, ) -from ..resource_info import OpenFermionExtra, OpenFermionResourceInfo +from .resource_info import OpenFermionExtra, OpenFermionResourceInfo @dataclasses.dataclass(frozen=True, unsafe_hash=True) @@ -124,7 +124,7 @@ def _cost_estimator( hardware_failure_tolerance: float = 1e-3, factory_count: int = 4, magic_state_factory_iterator: Optional[Iterable[MagicStateFactory]] = None, -): +) -> Tuple[CostEstimate, AlgorithmParameters]: """ Produce best cost in terms of physical qubits and real run time based on number of toffoli, number of logical qubits, and physical error rate. @@ -165,7 +165,7 @@ def _cost_estimator( best_cost = cost best_params = params - if best_cost is None: + if best_cost is None or best_params is None: raise RuntimeError( "Failed to find parameters that yield an acceptable failure probability. " "You must decrease the number of T gates and/or Toffolis in your circuit" @@ -174,7 +174,7 @@ def _cost_estimator( return best_cost, best_params -def footprint_estimator( +def openfermion_estimator( num_logical_qubits: int, num_toffoli: int = 0, num_t: int = 0, @@ -217,12 +217,12 @@ def footprint_estimator( resource_info = OpenFermionResourceInfo( n_physical_qubits=best_cost.physical_qubit_count, - n_logical_qubits=best_params.max_allocated_logical_qubits, total_time_in_seconds=best_cost.duration, + optimization="Space", code_distance=best_params.logical_data_qubit_distance, logical_error_rate=best_cost.algorithm_failure_probability, + n_logical_qubits=best_params.max_allocated_logical_qubits, decoder_info=decoder_info, - routing_to_measurement_volume_ratio=best_params.routing_overhead_proportion, magic_state_factory_name=best_params.magic_state_factory.name, extra=OpenFermionExtra( fail_rate_msFactory=best_params.magic_state_factory.distilled_magic_state_error_rate, # noqa: E501 diff --git a/src/benchq/resource_estimators/resource_info.py b/src/benchq/resource_estimators/resource_info.py index 5a3c5eeb..fd3a0258 100644 --- a/src/benchq/resource_estimators/resource_info.py +++ b/src/benchq/resource_estimators/resource_info.py @@ -4,14 +4,20 @@ """Data structures describing estimated resources and related info.""" from dataclasses import dataclass, field -from typing import Generic, List, Optional, TypeVar +from typing import Generic, Optional, TypeVar + +from benchq.compilation.graph_states.compiled_data_structures import ( + CompiledAlgorithmImplementation, +) + +from ..visualization_tools.resource_allocation import CycleAllocation, QubitAllocation TExtra = TypeVar("TExtra") @dataclass class DecoderInfo: - """Information relating the deceoder.""" + """Information relating the decoder.""" total_energy_in_joules: float power_in_watts: float @@ -55,50 +61,29 @@ class ResourceInfo(Generic[TExtra]): There are several variants of this class aliased below. """ + n_physical_qubits: int + total_time_in_seconds: float + optimization: str code_distance: int logical_error_rate: float n_logical_qubits: int - n_physical_qubits: int - total_time_in_seconds: float decoder_info: Optional[DecoderInfo] magic_state_factory_name: str - routing_to_measurement_volume_ratio: float extra: TExtra hardware_resource_info: Optional[DetailedIonTrapResourceInfo] = None @dataclass -class GraphData: - """Minimal set of graph-related data needed for resource estimation.""" +class GraphExtra: + """Extra info relating to resource estimation using Graph State Compilation.""" - max_graph_degree: int - n_nodes: int - n_t_gates: int - n_rotation_gates: int - n_measurement_steps: int + implementation: CompiledAlgorithmImplementation + time_allocation: Optional[CycleAllocation] + qubit_allocation: Optional[QubitAllocation] # Alias for type of resource info returned by GraphResourceEstimator -GraphResourceInfo = ResourceInfo[GraphData] - - -@dataclass -class ExtrapolatedGraphData(GraphData): - """GraphData extended with extrapolation-related info.""" - - n_logical_qubits_r_squared: float - n_measurement_steps_r_squared: float - n_nodes_r_squared: float - data_used_to_extrapolate: List[GraphData] = field(repr=False) - steps_to_extrapolate_to: int - - @property - def max_graph_degree_r_squared(self) -> float: - return self.n_logical_qubits_r_squared - - -# Alias for type of resource info returned by ExtrapolationResourceEstimator -ExtrapolatedGraphResourceInfo = ResourceInfo[ExtrapolatedGraphData] +GraphResourceInfo = ResourceInfo[GraphExtra] @dataclass @@ -110,7 +95,7 @@ class AzureExtra: raw_data: dict -# Alias for type of resource info returned by AzureResourceEstimator +# Alias for type of resource info returned by azure_estimator AzureResourceInfo = ResourceInfo[AzureExtra] @@ -119,7 +104,7 @@ class OpenFermionExtra: """Extra info relating to resource estimation using OpenFermion.""" fail_rate_msFactory: float - rounds_magicstateFactory: int + rounds_magicstateFactory: float scc_time: float physical_qubit_error_rate: float diff --git a/src/benchq/visualization_tools.py b/src/benchq/visualization_tools.py deleted file mode 100644 index b946cafe..00000000 --- a/src/benchq/visualization_tools.py +++ /dev/null @@ -1,174 +0,0 @@ -################################################################################ -# © Copyright 2022-2023 Zapata Computing Inc. -################################################################################ -from typing import List, Optional - -import matplotlib.pyplot as plt -import networkx as nx -import numpy as np -from scipy.optimize import minimize - -from .resource_estimators.resource_info import ( - ExtrapolatedGraphResourceInfo, - ResourceInfo, -) - - -def plot_graph_state_with_measurement_steps( - graph_state_graph, - measurement_steps, - cmap=plt.cm.rainbow, - name="extrapolation_plot", -): - """Plot a graph state with the measurement steps highlighted in different - colors. The measurement steps are given as a list of lists of nodes. Each - list of nodes is a measurement step. The nodes are given as a list of - tuples. Each tuple is a node and a measurement basis. The node is an - integer and the measurement basis is a string. The graph state is given as - a networkx graph. The nodes are integers and the edges are tuples of - integers. The cmap is the color map to use for the measurement steps. - Note: Only works when substrate scheduler is run in "fast" mode.""" - node_measurement_groupings = [ - [node[0] for node in row] for row in measurement_steps - ] - colors = cmap(np.linspace(0, 1, len(node_measurement_groupings))) - color_map = [] - for node in graph_state_graph: - for i, group in enumerate(node_measurement_groupings): - if int(node) in group: - color_map.append(colors[i]) - break - nx.draw(graph_state_graph, node_color=color_map, node_size=10) - # uncomment following lines to save graph image as well as show it - # plt.savefig(name + ".pdf") - # plt.clf() - plt.show() - - -def plot_extrapolations( - info: ExtrapolatedGraphResourceInfo, - steps_to_extrapolate_from: List[int], - n_measurement_steps_fit_type: str = "logarithmic", - exact_info: Optional[ResourceInfo] = None, -): - """Here we allow one to inspect the fits given by extrapolating a problem - from a smaller number of steps. If exact_info is provided, we also plot the - exact values for the problem size in green. The extrapolated point is plotted - in black. The points used to extrapolate are plotted in blue. The fit is plotted - in red. If the green or black dot is below the red line on the "n_nodes" plot, - then we are using a 20-to-4 magic state distillation factory and the "n_nodes" - was cut in 4 to compensate. This is fine because the original number of nodes - (without the division by 4) will always follow the red line. - """ - figure, axis = plt.subplots(3, 1) - figure.tight_layout(pad=1.5) - - for i, property in enumerate( - ["max_graph_degree", "n_measurement_steps", "n_nodes"] - ): - x = np.array(steps_to_extrapolate_from) - y = np.array( - [getattr(d, property) for d in info.extra.data_used_to_extrapolate] - ) - - # logarithmic extrapolation - if ( - property == "n_measurement_steps" - and n_measurement_steps_fit_type == "logarithmic" - ): - m, c, r_squared = _get_logarithmic_extrapolation(x, y) - - all_x = np.arange(1, info.extra.steps_to_extrapolate_to + 1, 1) - axis[i].plot( - all_x, - m * np.log(all_x) + c, - "r", - label="fitted line", - ) - else: - m, c, r_squared = _get_linear_extrapolation(x, y) - axis[i].plot( - [0, info.extra.steps_to_extrapolate_to], - [c, m * info.extra.steps_to_extrapolate_to + c], - "r", - label="fitted line", - ) - - axis[i].plot(x, y, "bo") - axis[i].plot( - [info.extra.steps_to_extrapolate_to], - [getattr(info.extra, property)], - "ko", - ) - if exact_info is not None: - axis[i].plot( - [info.extra.steps_to_extrapolate_to], - [getattr(exact_info.extra, property)], - "go", - ) - - axis[i].plot([], [], " ", label="r_squared: " + str(r_squared)) - axis[i].legend() - axis[i].set_title(property) - - plt.show() - - -def _get_logarithmic_extrapolation(x, y): - x = np.array(x) - y = np.array(y) - - def _logarithmic_objective(params): - a, b = params - y_pred = a * np.log(x) + b - error = y_pred - y - return np.sum(error**2) - - a_opt, b_opt = _extrapolate(x, y, _logarithmic_objective) - - # Calculate R-squared value - y_mean = np.mean(y) - total_sum_of_squares = np.sum((y - y_mean) ** 2) - residual_sum_of_squares = np.sum((y - (a_opt * np.log(x) + b_opt)) ** 2) - r_squared = 1 - (residual_sum_of_squares / total_sum_of_squares) - - return a_opt, b_opt, r_squared - - -def _get_linear_extrapolation(x, y): - x = np.array(x) - y = np.array(y) - - def _linear_objective(params): - a, b = params - y_pred = a * x + b - error = y_pred - y - return np.sum(error**2) - - a_opt, b_opt = _extrapolate(x, y, _linear_objective) - - # Calculate R-squared value - y_mean = np.mean(y) - total_sum_of_squares = np.sum((y - y_mean) ** 2) - residual_sum_of_squares = np.sum((y - (a_opt * x + b_opt)) ** 2) - r_squared = 1 - (residual_sum_of_squares / total_sum_of_squares) - - return a_opt, b_opt, r_squared - - -def _extrapolate(x, y, objective): - # Define the constraint that the slope (a) must be greater than zero - def slope_constraint(params): - a, _ = params - return a - - # Perform the optimization - initial_guess = [1.0, 1.0] - bounds = [(0, None), (None, None)] - constraints = {"type": "ineq", "fun": slope_constraint} - result = minimize(objective, initial_guess, bounds=bounds, constraints=constraints) - - # Extrapolated to desired point - a_opt, b_opt = result.x - - return a_opt, b_opt diff --git a/src/benchq/visualization_tools/plot_graph_state.py b/src/benchq/visualization_tools/plot_graph_state.py new file mode 100644 index 00000000..fd6cd906 --- /dev/null +++ b/src/benchq/visualization_tools/plot_graph_state.py @@ -0,0 +1,230 @@ +from typing import List + +import matplotlib.patches as mpatches +import matplotlib.pyplot as plt +import networkx as nx +import numpy as np +from matplotlib.lines import Line2D + + +def plot_graph_state(asg, pauli_tracker): + """Converts an adjacency list to an adjacency matrix. + + Args: + adj: The adjacency list to convert. + + Returns: + The adjacency matrix. + """ + adj, lco, input_nodes, output_nodes = ( + asg["edge_data"], + asg["sqs"], + asg["stitching_properties"]["graph_input_nodes"], + asg["stitching_properties"]["graph_output_nodes"], + ) + + plt.subplot(1, 2, 1) + plt.title("Graph State") + + # Create the adjacency matrix. + adjacency_matrix = [[0 for _ in range(len(adj))] for _ in range(len(adj))] + + # Iterate over the adjacency list and fill in the adjacency matrix. + for node, neighbors in enumerate(adj): + for neighbor in neighbors: + adjacency_matrix[node][neighbor] = 1 + + graph = nx.from_numpy_array(np.array(adjacency_matrix)) + + # Remove isolated nodes + # isolated_nodes = [ + # node for node, degree in dict(graph.degree()).items() if degree == 0 + # ] + # graph.remove_nodes_from(isolated_nodes) + + # Create a legend for node colors + spacial_node_colors = { + "I": "grey", + "S": "lime", + "H": "red", + "HSH": "magenta", + "HS": "cyan", + "SH": "orange", + } + legend_patches = [ + mpatches.Patch(color=color, label=node) + for node, color in spacial_node_colors.items() + ] + + # Plot a graph with lco labels + color_map = [] + for node, lco in enumerate(lco): + if lco == 1: + color_map.append(spacial_node_colors["I"]) + elif lco == 2: + color_map.append(spacial_node_colors["S"]) + elif lco == 3: + color_map.append(spacial_node_colors["H"]) + elif lco == 4: + color_map.append(spacial_node_colors["HSH"]) + elif lco == 5: + color_map.append(spacial_node_colors["HS"]) + elif lco == 6: + color_map.append(spacial_node_colors["SH"]) + else: + raise ValueError(f"lco {lco} not supported.") + + legend_patches += [ + Line2D( + [0], + [0], + marker="s", + color="black", + label="Input", + markerfacecolor="w", + markersize=10, + ), + Line2D( + [0], + [0], + marker="o", + color="black", + label="Intermediate", + markerfacecolor="w", + markersize=10, + ), + Line2D( + [0], + [0], + marker="d", + color="black", + label="Output", + markerfacecolor="w", + markersize=10, + ), + ] + + plt.legend(handles=legend_patches, loc="upper right") + for node in graph.nodes: + if node in input_nodes: + graph.nodes[node]["shape"] = "s" + elif node in output_nodes: + graph.nodes[node]["shape"] = "d" + else: + graph.nodes[node]["shape"] = "o" + + # Drawing the graph + # First obtain the node positions using one of the layouts + nodePos = nx.layout.spring_layout(graph) + + # The rest of the code here attempts to automate the whole process by + # first determining how many different node classes (according to + # attribute 's') exist in the node set and then repeatedly calling + # draw_networkx_node for each. Perhaps this part can be optimized further. + + # Get all distinct node classes according to the node shape attribute + nodeShapes = set((aShape[1]["shape"] for aShape in graph.nodes(data=True))) + + # For each node class... + for aShape in nodeShapes: + # ...filter and draw the subset of nodes with the same symbol in the positions + # that are now known through the use of the layout. + nodes_with_this_shape = [ + sNode[0] + for sNode in filter( + lambda x: x[1]["shape"] == aShape, graph.nodes(data=True) + ) + ] + colors = [ + color_map[i] for i in nodes_with_this_shape if 0 <= i < len(color_map) + ] + + nx.draw_networkx_nodes( + graph, + nodePos, + node_shape=aShape, + nodelist=nodes_with_this_shape, + node_color=colors, # pyright: ignore[reportArgumentType] + node_size=120, + ) + nx.draw_networkx_labels(graph, nodePos) + + # Finally, draw the edges between the nodes + nx.draw_networkx_edges(graph, nodePos) + + # create graph for pauli flow + plt.subplot(1, 2, 2) + plt.title("Pauli Flow") + x_pauli_flow = nx.DiGraph() + z_pauli_flow = nx.DiGraph() + + # Add node + # s and edges from the adjacency list + for node, neighbors in enumerate(pauli_tracker["cond_paulis"]): + x_pauli_flow.add_node(node) + z_pauli_flow.add_node(node) + for neighbor in neighbors[0]: + x_pauli_flow.add_edge(neighbor, node, color="red") + for neighbor in neighbors[1]: + z_pauli_flow.add_edge(neighbor, node, color="blue") + + x_temporal_edge_colors = [ + x_pauli_flow[u][v]["color"] for u, v in x_pauli_flow.edges() + ] + z_temporal_edge_colors = [ + z_pauli_flow[u][v]["color"] for u, v in z_pauli_flow.edges() + ] + + # Create positions based on layering + pos = {} + for i, layer in enumerate(pauli_tracker["layering"]): + for j, node in enumerate(layer): + pos[node] = ( + j, + -i, + ) # Adjust the y-coordinate for vertical spacing + + # Plot the graph + nx.draw( + x_pauli_flow, + pos, + edge_color=x_temporal_edge_colors, + with_labels=True, + arrows=True, + connectionstyle="arc3,rad=0.2", + ) + nx.draw( + z_pauli_flow, + pos, + edge_color=z_temporal_edge_colors, + with_labels=True, + arrows=True, + connectionstyle="arc3,rad=-0.2", + ) + + # Add dashed lines between layers + max_layer_width = max([len(layer) for layer in pauli_tracker["layering"]]) + for layer_index in range(1, len(pauli_tracker["layering"])): + plt.plot( + [-0.5, max_layer_width - 0.5], + [-layer_index + 0.5, -layer_index + 0.5], + "k--", + lw=1, + alpha=0.5, + ) + + plt.tight_layout() + # Create a legend + red_patch = plt.Line2D( # pyright: ignore[reportPrivateImportUsage] + [0], [0], marker="o", color="w", markerfacecolor="red", markersize=8, label="X" + ) + blue_patch = plt.Line2D( # pyright: ignore[reportPrivateImportUsage] + [0], [0], marker="o", color="w", markerfacecolor="blue", markersize=8, label="Z" + ) + + # Display the legend + plt.legend(handles=[red_patch, blue_patch], loc="lower right") + + plt.show() + + return graph diff --git a/src/benchq/visualization_tools/plot_substrate_scheduling.py b/src/benchq/visualization_tools/plot_substrate_scheduling.py new file mode 100644 index 00000000..6f7fa0fb --- /dev/null +++ b/src/benchq/visualization_tools/plot_substrate_scheduling.py @@ -0,0 +1,58 @@ +################################################################################ +# © Copyright 2022-2023 Zapata Computing Inc. +################################################################################ +from copy import copy +from typing import Tuple + +import matplotlib.pyplot as plt +import networkx as nx +import numpy as np + + +def plot_graph_state_with_measurement_steps( + asg, + measurement_steps, + cmap=plt.cm.rainbow, # pyright: ignore[reportAttributeAccessIssue] + name="extrapolation_plot", +): + """Plot a graph state with the measurement steps highlighted in different + colors. The measurement steps are given as a list of lists of nodes. Each + list of nodes is a measurement step. The nodes are given as a list of + tuples. Each tuple is a node and a measurement basis. The node is an + integer and the measurement basis is a string. The graph state is given as + a networkx graph. The nodes are integers and the edges are tuples of + integers. The cmap is the color map to use for the measurement steps. + Note: Only works when substrate scheduler is run in "fast" mode.""" + graph_state_graph = nx.Graph() + for node, neighbors in enumerate(asg["edge_data"]): + for neighbor in neighbors: + graph_state_graph.add_edge(node, neighbor) + _, graph_state_graph = remove_isolated_nodes_from_graph(graph_state_graph) + + node_measurement_groupings = [ + [node[0] for node in row] for row in measurement_steps + ] + colors = cmap(np.linspace(0, 1, len(node_measurement_groupings))) + color_map = [] + for node in graph_state_graph: + for i, group in enumerate(node_measurement_groupings): + if int(node) in group: + color_map.append(colors[i]) + break + + nx.draw(graph_state_graph, node_color=color_map, node_size=10) + # uncomment following lines to save graph image as well as show it + # plt.savefig(name + ".pdf") + # plt.clf() + plt.show() + + +def remove_isolated_nodes_from_graph(graph: nx.Graph) -> Tuple[int, nx.Graph]: + cleaned_graph = copy(graph) + isolated_nodes = list(nx.isolates(cleaned_graph)) + n_nodes_removed = len(isolated_nodes) + + cleaned_graph.remove_nodes_from(isolated_nodes) + cleaned_graph = nx.convert_node_labels_to_integers(cleaned_graph) + + return n_nodes_removed, cleaned_graph diff --git a/src/benchq/visualization_tools/resource_allocation.py b/src/benchq/visualization_tools/resource_allocation.py new file mode 100644 index 00000000..6c3f217e --- /dev/null +++ b/src/benchq/visualization_tools/resource_allocation.py @@ -0,0 +1,278 @@ +import itertools +from copy import copy +from typing import Optional + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +from matplotlib.axes import Axes +from matplotlib.colors import LinearSegmentedColormap +from upsetplot import UpSet + +default_process_types = {"distillation", "Tstate-to-Tgate", "entanglement"} + + +class ResourceAllocation: + def __init__(self, resource_name, process_types=default_process_types): + """Initialize the ResourceAllocation object. We use the object to track + the number of resources used by different combinations of processes. + + Attributes: + allocation_data (dict): a dictionary that maps a frozenset of process + types to the number of resources that are used by that combination of + processes exclusively. + """ + self.resource_name = resource_name + self.process_types = process_types + self.allocation_data = {} + for combo in all_combinations(self.process_types): + self.allocation_data[frozenset(combo)] = 0 + + def log(self, resources: float, *processes): + """Add resources to the given processes.""" + assert resources >= 0 + self.allocation_data[frozenset(processes)] += resources + + def log_parallelized(self, resource_tuple, processes_tuple): + """Add the resources used by processes that start at the same time. + + Args: + resource_tuple (tuple): a tuple of the number of resources used by each + process. + processes_tuple (tuple): a tuple of the processes that start at the same + time. + """ + assert len(resource_tuple) == len(processes_tuple) + for resources in resource_tuple: + assert resources >= 0 + + combined_tuple = list(zip(resource_tuple, processes_tuple)) + combined_tuple.sort(key=lambda x: x[0]) + combined_tuple.reverse() + + for i in range(len(combined_tuple) - 1): + self.log( + combined_tuple[i][0] - combined_tuple[i + 1][0], + *tuple(tup[1] for tup in combined_tuple[: i + 1]), + ) + self.log( + combined_tuple[-1][0], + *processes_tuple, + ) + + @property + def total(self): + return sum(self.allocation_data.values()) + + def exclusive(self, *processes): + """Return the number of resources that are exclusive to the given processes. + + Returns: + float: number of resources + """ + return self.allocation_data[frozenset(processes)] + + def inclusive(self, *processes): + """Return the total number of resources that include the given processes. + This includes resources that are shared with other processes. + + Returns: + float: number of resources + """ + return sum( + [ + self.allocation_data[combo] + for combo in self.allocation_data + if all([process in combo for process in processes]) + ] + ) + + def __repr__(self): + return ( + str(self.allocation_data) + .replace("frozenset", "") + .replace("(", "") + .replace(")", "") + .replace("'", "") + ) + + def to_pandas_dataframe(self): + data = [] + for processes, resources in self.allocation_data.items(): + if resources != 0: + row = {process: process in processes for process in self.process_types} + row[self.resource_name] = resources + data.append(row) + df = pd.DataFrame(data) + df.fillna(False, inplace=True) + return df + + def plot(self): + upset = self.plot_upset_plot(is_subplot=True) + self.plot_stacked_bar_chart(is_subplot=True, ax=upset["totals"]) + plt.close(2) # Closes the empty second figure + plt.show() + + def plot_upset_plot(self, is_subplot=False): + """Plot a bar chart showing the time used by each process type.""" + df = self.to_pandas_dataframe() + # Prepare the dataset for the upset plot by + # summing up the resources for each combination + subset_data = df.groupby(list(self.process_types))[self.resource_name].sum() + # Generating the upset plot + upset = UpSet( + subset_data, + sort_by="cardinality", + orientation="vertical", + show_percentages=True, + ) + + axes_dict = upset.plot() + + # Changing the labels + # axes_dict["totals"].set_ylabel("Total Cycles for\n each Process Type") + axes_dict["intersections"].set_xlabel(self.resource_name) + + plt.title("Parallelization Breakdown") + + # Show the plot + if not is_subplot: + plt.show() + + return axes_dict + + def plot_stacked_bar_chart(self, is_subplot=False, ax=None): + if ax is None: + ax = plt + process_types = self.process_types + elif is_subplot: + assert isinstance(ax, Axes) + process_types = [tick.get_text() for tick in ax.get_xticklabels()] + else: + raise ValueError("Axes can only be provided the plot is a subplot") + + init_resources = [0] * len(process_types) + data = {i + 1: copy(init_resources) for i in range(len(process_types))} + for combo in all_combinations(process_types): + for process_index, process in enumerate(process_types): + if process in combo: + data[len(combo)][process_index] += self.exclusive(*combo) + + # Number of categories and subcategories + n_categories = len(process_types) + sub_categories = list(data.keys()) + n_sub_categories = len(sub_categories) + + # Define the positions for the categories + ind = np.arange(n_categories) + + # Define a color map from red to green + color_map = LinearSegmentedColormap.from_list( + "gr", ["green", "yellow", "red"], N=n_sub_categories + ) + + # Base height for the stacked bars + height_cumulative = np.zeros(n_categories) + + # Labeling and legend + if is_subplot: + assert isinstance(ax, Axes) + ax.cla() + ax.set_ylabel(self.resource_name) + ax.set_title("Total " + self.resource_name + " \nfor each Process") + ax.set_xticks(ind) + ax.set_xticklabels(process_types) + ax.set_xlabel("Process Types") + else: + # can't get pyright to recognize the type of ax as plt here + ax.ylabel(self.resource_name) # type: ignore + ax.title( # type: ignore + "Total " + self.resource_name + " for each Process" + ) + ax.xticks(ind, process_types) # type: ignore + ax.xlabel("Process Types") # type: ignore + + # Plot each sub-category + for i, (sub_category, values) in reversed(list(enumerate(data.items()))): + ax.bar( + ind, + values, + color=color_map(i / (n_sub_categories - 1)), + edgecolor="black", + label=sub_category, + bottom=height_cumulative, + ) + height_cumulative += np.array(values) + + ax.legend( + title="Number of\nParallel Processes", + bbox_to_anchor=(1.05, 1), + loc="upper left", + ) + + if not is_subplot: + ax.tight_layout() # type: ignore + plt.show() + + fig, axes = plt.subplots() + + return axes + + +def all_combinations(iterable): + # Loop over all lengths from 1 to max_length (inclusive) + max_length = len(iterable) + for r in range(1, max_length + 1): + # Generate and yield combinations of the current length + for combo in itertools.combinations(iterable, r): + yield combo + + +class CycleAllocation(ResourceAllocation): + def __init__(self, process_types=default_process_types): + super().__init__("cycles", process_types) + + def __add__(self, other, safe=False): + new_data = CycleAllocation(self.process_types) + for combo in self.allocation_data: + new_data.allocation_data[combo] = self.allocation_data[combo] + for combo in other.allocation_data: + new_data.allocation_data[combo] += other.allocation_data[combo] + return new_data + + +class QubitAllocation(ResourceAllocation): + def __init__(self, process_types=default_process_types): + super().__init__("qubits", process_types) + + def get_num_logical_qubits(self, physical_qubits_per_logical_qubit): + """Return the number of logical qubits that are being used by the computation. + Assumes that all qubits not being used for distillation are being used for + computation.""" + physical_qubits_not_used_for_distillation = 0 + for combo in all_combinations(self.process_types): + if "distillation" not in combo: + physical_qubits_not_used_for_distillation += self.exclusive(*combo) + + num_logical_qubits = ( + physical_qubits_not_used_for_distillation + / physical_qubits_per_logical_qubit + ) + + if num_logical_qubits != int(num_logical_qubits): + raise ValueError("The number of logical qubits must be an integer.") + + return int(num_logical_qubits) + + def get_num_factories(self, physical_qubits_per_factory): + """Return the number of magic state factories that are being used by the + computation. Assumes that all qubits being used for exclusively distillation + are in factories.""" + num_distillation_qubits = self.exclusive("distillation") + num_factories = num_distillation_qubits / physical_qubits_per_factory + + if num_factories != int(num_factories): + raise ValueError("The number of factories must be an integer.") + + return int(num_factories) diff --git a/tests/benchq/compilation/single_rotation.qasm b/tests/benchq/compilation/single_rotation.qasm index ed5995d8..3fd5c04d 100644 --- a/tests/benchq/compilation/single_rotation.qasm +++ b/tests/benchq/compilation/single_rotation.qasm @@ -1,5 +1,5 @@ OPENQASM 2.0; include "qelib1.inc"; -qreg q[4]; +qreg q[0]; h q[0]; rz(0.20103392) q[0]; diff --git a/tests/benchq/compilation/test_asg_stitching.py b/tests/benchq/compilation/test_asg_stitching.py new file mode 100644 index 00000000..63f97281 --- /dev/null +++ b/tests/benchq/compilation/test_asg_stitching.py @@ -0,0 +1,381 @@ +import os + +import numpy as np +import pytest +import test_rbs_with_pauli_tracking # type: ignore +from orquestra.quantum.circuits import CNOT, CZ, RZ, Circuit, H, I, S, T, X, Y, Z + +from benchq.compilation.graph_states import jl +from benchq.visualization_tools.plot_graph_state import plot_graph_state + +SKIP_SLOW = pytest.mark.skipif( + os.getenv("SLOW_BENCHMARKS") is None, + reason="Slow benchmarks can only run if SLOW_BENCHMARKS env variable is defined", +) + +np.random.seed(0) + + +def check_correctness_for_stitched_circuits( + circuit, + asg, + pauli_tracker, + init, + show_graph=False, + show_circuit=False, +): + if show_graph: + plot_graph_state(asg, pauli_tracker) + + pdf = test_rbs_with_pauli_tracking.simulate( + circuit, + init, + asg, + pauli_tracker, + show_circuit=show_circuit, + ) + + # Format the pdf for printing + binary_distribution = {} + n = len(pdf) + + all_bitstrings = [ + format(i, f"0{circuit._n_qubits}b") for i in range(2**circuit._n_qubits) + ] + + for i in range(n): + binary_distribution[all_bitstrings[i]] = pdf[i] + reversed_prob_density = {} + for binary_str, probability in binary_distribution.items(): + reversed_binary_str = binary_str[::-1] # Reverse the binary string + reversed_prob_density[reversed_binary_str] = probability + + correct_pdf = { + bitstring: 1.0 if bitstring == "0" * circuit._n_qubits else 0.0 + for bitstring in all_bitstrings + } + if reversed_prob_density != correct_pdf: + raise Exception("Incorrect Result Detected!") + + +def get_graph(circuit, hyperparams, connection_type, optimization, max_num_qubits=3): + if connection_type == "input": + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + circuit, + verbose=False, + takes_graph_input=True, + gives_graph_output=False, + manually_stitchable=True, + optimization=optimization, + max_num_qubits=max_num_qubits, + hyperparams=hyperparams, + max_time=1e8, + ) + elif connection_type == "output": + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + circuit, + verbose=False, + takes_graph_input=False, + gives_graph_output=True, + manually_stitchable=True, + optimization=optimization, + max_num_qubits=max_num_qubits, + hyperparams=hyperparams, + max_time=1e8, + ) + elif connection_type == "both": + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + circuit, + verbose=False, + takes_graph_input=True, + gives_graph_output=True, + manually_stitchable=True, + optimization=optimization, + max_num_qubits=max_num_qubits, + hyperparams=hyperparams, + max_time=1e8, + ) + elif connection_type == "neither": + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + circuit, + verbose=False, + takes_graph_input=False, + gives_graph_output=False, + manually_stitchable=True, + optimization=optimization, + max_num_qubits=max_num_qubits, + hyperparams=hyperparams, + max_time=1e8, + ) + else: + raise ValueError(f"connection_type {connection_type} not supported.") + + return asg, pauli_tracker + + +def to_python(asg, pauli_tracker): + return jl.python_asg(asg), jl.python_pauli_tracker(pauli_tracker) + + +ghz_circuit = Circuit([H(0), CNOT(0, 1), CNOT(0, 2)]) + + +@SKIP_SLOW +@pytest.mark.parametrize("optimization", ["Space", "Time", "Variable"]) +@pytest.mark.parametrize( + "init", + [ + # All start in Z basis + Circuit([]), + # Some start in X basis, one in Z basis + Circuit([H(0), H(1)]), + # All start in X basis + Circuit([H(0), H(1), H(2)]), + # all start in Y basis + Circuit([H(0), S(0), H(1), S(1), H(2), S(2)]), + ], +) +@pytest.mark.parametrize( + "circuit_1, circuit_2, circuit_3", + [ + (ghz_circuit, ghz_circuit, ghz_circuit), + ( + Circuit( + [ + Y(2), + Y(2), + CNOT(1, 0), + X(1), + RZ(1.3856216182779741)(2), + ] + ), + Circuit( + [ + RZ(3.9206180253660037)(1), + CZ(2, 0), + X(1), + CNOT(0, 1), + H(2), + ] + ), + Circuit( + [ + X(1), + H(2), + T(1), + RZ(1.8024498348644822)(1), + X(2), + ] + ), + ), + ( + # test T gates work as expected + Circuit( + [ + T.dagger(2), + T(2), + T(2), + X(1), + Z(1), + ] + ), + Circuit( + [ + Z(1), + T(2), + CZ(1, 2), + Z(1), + Y(2), + ] + ), + Circuit( + [ + H(1), + S(1), + S(1), + Z(2), + CZ(0, 1), + ] + ), + ), + ], +) +def test_triple_stitched_circuit_produces_correct_result( + optimization, init, circuit_1, circuit_2, circuit_3 +): + hyperparams = jl.RbSHyperparams(3, 2, 6, 1e5, 0) + + asg_1, pauli_tracker_1 = get_graph( + init + circuit_1, hyperparams, "output", optimization + ) + # plot_graph_state(*to_python(asg_1, pauli_tracker_1)) + asg_2, pauli_tracker_2 = get_graph(circuit_2, hyperparams, "both", optimization) + # plot_graph_state(*to_python(asg_2, pauli_tracker_2)) + asg_3, pauli_tracker_3 = get_graph(circuit_3, hyperparams, "input", optimization) + # plot_graph_state(*to_python(asg_3, pauli_tracker_3)) + + # combine graphs + asg_12, pauli_tracker_12 = jl.stitch_graphs( + asg_1, pauli_tracker_1, asg_2, pauli_tracker_2 + ) + # plot_graph_state(*to_python(asg_12, pauli_tracker_12)) + asg_123, pauli_tracker_123 = jl.stitch_graphs( + asg_12, pauli_tracker_12, asg_3, pauli_tracker_3 + ) + # plot_graph_state(*to_python(asg_123, pauli_tracker_123)) + + asg, pauli_tracker = to_python(asg_123, pauli_tracker_123) + check_correctness_for_stitched_circuits( + circuit_1 + circuit_2 + circuit_3, + asg, + pauli_tracker, + init, + show_graph=False, + show_circuit=True, + ) + + +@pytest.mark.parametrize("optimization", ["Space", "Time", "Variable"]) +@pytest.mark.parametrize( + "circuit_1, circuit_2", + [ + (ghz_circuit, ghz_circuit), + ( + # test rotations work as expected + Circuit( + [ + Y(2), + Y(2), + CNOT(1, 0), + X(1), + RZ(1.3856216182779741)(2), + ] + ), + Circuit( + [ + RZ(3.9206180253660037)(1), + CZ(2, 0), + X(1), + CNOT(0, 1), + H(2), + ] + ), + ), + ( + # test T gates work as expected + Circuit( + [ + T.dagger(2), + T(2), + T(2), + X(1), + Z(1), + ] + ), + Circuit( + [ + Z(1), + T(2), + CZ(1, 2), + Z(1), + Y(2), + ] + ), + ), + ], +) +def test_double_stitched_circuit_produces_correct_result( + optimization, circuit_1, circuit_2 +): + hyperparams = jl.RbSHyperparams(3, 2, 6, 1e5, 0) + init = Circuit([H(0), H(1), H(2)]) + + asg_1, pauli_tracker_1 = get_graph( + init + circuit_1, hyperparams, "output", optimization + ) + # plot_graph_state(*to_python(asg_1, pauli_tracker_1)) + asg_2, pauli_tracker_2 = get_graph(circuit_2, hyperparams, "input", optimization) + # plot_graph_state(*to_python(asg_2, pauli_tracker_2)) + + # combine graphs + asg_12, pauli_tracker_12 = jl.stitch_graphs( + asg_1, pauli_tracker_1, asg_2, pauli_tracker_2 + ) + # plot_graph_state(*to_python(asg_12, pauli_tracker_12)) + + asg, pauli_tracker = to_python(asg_12, pauli_tracker_12) + check_correctness_for_stitched_circuits( + circuit_1 + circuit_2, + asg, + pauli_tracker, + init, + show_graph=False, + show_circuit=True, + ) + + +# If you run this test, it will take a long time to complete. Make sure to +# run it with the -s option so that you can see the circuits being printed +# as well as the progress of the test. +@SKIP_SLOW +def test_1000_large_random_circuits(): + for n_circuits_checked in range(1000): + # randomize hyperparams + teleportation_threshold = np.random.randint(1, 10) + teleportation_depth = np.random.randint(1, 3) * 2 + min_neighbor_degree = np.random.randint(5, 20) + hyperparams = jl.RbSHyperparams( + teleportation_threshold, teleportation_depth, min_neighbor_degree, 1e5, 0 + ) + + init = Circuit([H(0), H(1), H(2)]) + + optimization = np.random.choice(["Space", "Time", "Variable"]) + + n_qubits = 4 + depth = 10 + circuit_1 = test_rbs_with_pauli_tracking.generate_random_circuit( + n_qubits, depth + ) + circuit_2 = test_rbs_with_pauli_tracking.generate_random_circuit( + n_qubits, depth + ) + asg_1, pauli_tracker_1 = get_graph( + init + circuit_1, hyperparams, "output", optimization + ) + # plot_graph_state(*to_python(asg_1, pauli_tracker_1)) + asg_2, pauli_tracker_2 = get_graph( + circuit_2, hyperparams, "input", optimization + ) + # plot_graph_state(*to_python(asg_2, pauli_tracker_2)) + + # combine graphs + asg_12, pauli_tracker_12 = jl.stitch_graphs( + asg_1, pauli_tracker_1, asg_2, pauli_tracker_2 + ) + # plot_graph_state(*to_python(asg_12, pauli_tracker_12)) + + asg, pauli_tracker = to_python(asg_12, pauli_tracker_12) + check_correctness_for_stitched_circuits( + circuit_1 + circuit_2, + asg, + pauli_tracker, + init, + show_graph=False, + show_circuit=True, + ) + + print( + "\033[92m" + + f"{n_circuits_checked} circuits checked successfully!" + + "\033[0m" + ) + n_circuits_checked += 1 + + +# if __name__ == "__main__": +# test_double_stitched_circuit_produces_correct_result( +# "Time", +# Circuit([H(0), CNOT(0, 1), CNOT(0, 2), CNOT(0, 3)]), +# Circuit([H(0), CNOT(0, 1), CNOT(0, 2), CNOT(0, 3)]), +# ) diff --git a/tests/benchq/compilation/test_pyLIQTR_compilation.py b/tests/benchq/compilation/test_pyLIQTR_compilation.py index de529c72..7a28c3e8 100644 --- a/tests/benchq/compilation/test_pyLIQTR_compilation.py +++ b/tests/benchq/compilation/test_pyLIQTR_compilation.py @@ -3,10 +3,10 @@ ################################################################################ import numpy as np import pytest -from cirq import CNOT as CirqCNOT -from cirq import H as CirqH -from cirq import LineQubit -from cirq.circuits import Circuit as CirqCircuit +from cirq.circuits.circuit import Circuit as CirqCircuit +from cirq.devices.line_qubit import LineQubit +from cirq.ops.common_gates import CNOT as CirqCNOT +from cirq.ops.common_gates import H as CirqH from numpy import linalg as LA from orquestra.quantum.circuits import CNOT as OrquestraCNOT from orquestra.quantum.circuits import RX, RZ @@ -14,7 +14,7 @@ from orquestra.quantum.circuits import H as OrquestraH from qiskit.circuit import QuantumCircuit as QiskitCircuit -from benchq.compilation import pyliqtr_transpile_to_clifford_t +from benchq.compilation.circuits import pyliqtr_transpile_to_clifford_t two_qubit_qiskit_circuit = QiskitCircuit(2) two_qubit_qiskit_circuit.cx(0, 1) @@ -30,9 +30,9 @@ ) def test_clifford_circuit_produces_correct_output(circuit): """Tests that clifford circuits are unchanged""" - pyliqtr_transpile_to_clifford_t(circuit, gate_precision=0.001) == OrquestraCircuit( - [OrquestraCNOT(0, 1), OrquestraH(0)] - ) + assert pyliqtr_transpile_to_clifford_t( + circuit, gate_precision=0.001 + ) == OrquestraCircuit([OrquestraCNOT(0, 1), OrquestraH(0)]) @pytest.mark.parametrize("gate_precision", [1e-3, 1e-6, 1e-10, 1.2e-6]) diff --git a/tests/benchq/compilation/test_rbs_hyperparam_tuning.py b/tests/benchq/compilation/test_rbs_hyperparam_tuning.py deleted file mode 100644 index 59029e73..00000000 --- a/tests/benchq/compilation/test_rbs_hyperparam_tuning.py +++ /dev/null @@ -1,291 +0,0 @@ -import os -import random -import string - -import pytest -from orquestra.quantum.circuits import CNOT, Circuit, H - -from benchq.compilation import transpile_to_native_gates -from benchq.compilation.rbs_hyperparam_tuning import ( - create_estimated_rbs_time_objective_fn, - create_space_time_objective_fn, - estimated_time_cost_from_rbs, - get_optimal_hyperparams_for_estimated_rbs_time, - get_optimal_hyperparams_for_space, - get_optimal_hyperparams_for_space_and_time, - get_optimal_hyperparams_for_time, - space_time_cost_from_rbs, -) - - -@pytest.fixture() -def large_circuit(): - size = 200 - circ = Circuit( - [ - H(0), - *[CNOT(j, i) for i in range(1, size) for j in range(0, size)], - ] - ) - return transpile_to_native_gates(circ) - - -@pytest.fixture() -def small_circuit(): - circ = Circuit([H(0), CNOT(0, 1)]) - return transpile_to_native_gates(circ) - - -SKIP_SLOW = pytest.mark.skipif( - os.getenv("SLOW_BENCHMARKS") is None, - reason="Slow benchmarks can only run if SLOW_BENCHMARKS env variable is defined", -) - - -@pytest.mark.parametrize("space_or_time", ["space", "time"]) -def test_space_time_cost_function_from_rbs_large_overrun(small_circuit, space_or_time): - # when - cost = space_time_cost_from_rbs( - rbs_iteration_time=0.1, - max_allowed_time=-100.0, - space_or_time=space_or_time, - circuit=small_circuit, - ) - - # then - assert cost > 10000000 - - -@pytest.mark.parametrize("space_or_time", ["space", "time"]) -def test_space_time_cost_function_from_rbs_no_overrun(small_circuit, space_or_time): - # when - cost = space_time_cost_from_rbs( - rbs_iteration_time=0.1, - max_allowed_time=1.0, - space_or_time=space_or_time, - circuit=small_circuit, - ) - - # then - assert cost < 10 - - -def test_space_and_time_cost_function_from_rbs_large_overrun(small_circuit): - # when - space_cost, time_cost = space_time_cost_from_rbs( - rbs_iteration_time=0.1, - max_allowed_time=-100.0, - space_or_time="space&time", - circuit=small_circuit, - ) - - # then - assert space_cost > 10000000 - assert time_cost > 10000000 - - -def test_space_and_time_cost_function_from_rbs_no_overrun(small_circuit): - # when - space_cost, time_cost = space_time_cost_from_rbs( - rbs_iteration_time=0.1, - max_allowed_time=1.0, - space_or_time="space&time", - circuit=small_circuit, - ) - - # then - assert space_cost < 10 - assert time_cost < 10 - - -@pytest.mark.skip(reason="very random, can't get it to pass consistently") -@pytest.mark.parametrize("space_or_time", ["space", "time"]) -def test_only_part_of_circuit_gives_same_cost(large_circuit, space_or_time): - # given - prop_to_test = 0.75 - - # when - full_cost = space_time_cost_from_rbs( - rbs_iteration_time=0.1, - max_allowed_time=1.0, - space_or_time=space_or_time, - circuit=large_circuit, - ) - partial_cost = space_time_cost_from_rbs( - rbs_iteration_time=0.1, - max_allowed_time=1.0, - space_or_time=space_or_time, - circuit=large_circuit, - circuit_prop_estimate=prop_to_test, - ) - - assert partial_cost / 2 <= full_cost <= partial_cost * 2 - - -@pytest.mark.parametrize("space_or_time", ["space", "time"]) -def test_completing_whole_iteration_when_unexpected_gives_error( - small_circuit, space_or_time -): - # given - prop_to_test = 0.1 - - # when/then - with pytest.raises(RuntimeError): - space_time_cost_from_rbs( - rbs_iteration_time=1.0, - max_allowed_time=1.0, - space_or_time=space_or_time, - circuit=small_circuit, - circuit_prop_estimate=prop_to_test, - ) - - -def test_incorrect_spacetime_option_raises_error(small_circuit): - # given - random_string = "".join(random.choices(string.ascii_letters, k=5)) - print(random_string) - - # when/then - with pytest.raises(ValueError): - space_time_cost_from_rbs( - rbs_iteration_time=0.1, - max_allowed_time=-100.0, - space_or_time=random_string, - circuit=small_circuit, - ) - - -def test_estimated_time_cost_function_from_rbs(large_circuit, small_circuit): - # when - large_time = estimated_time_cost_from_rbs( - rbs_iteration_time=0.1, circuit=large_circuit - ) - small_time = estimated_time_cost_from_rbs( - rbs_iteration_time=0.1, circuit=small_circuit - ) - - # then - assert large_time > small_time - - -def test_create_space_time_objective_function_sanity_check(small_circuit): - # when - objective = create_space_time_objective_fn( - rbs_iteration_time=1.0, - max_allowed_time=10.0, - space_or_time="space&time", - circuit=small_circuit, - ) - - # then - assert callable(objective) - - -def test_create_estimated_rbs_time_objective_fn_sanity_check(small_circuit): - # when - objective = create_estimated_rbs_time_objective_fn( - rbs_iteration_time=1.0, - circuit=small_circuit, - ) - - # then - assert callable(objective) - - -@SKIP_SLOW -def test_get_optimal_hyperparams_for_space(large_circuit): - # when - optimal_params = get_optimal_hyperparams_for_space( - rbs_iteration_time=0.2, - max_allowed_time=0.8, - circuit=large_circuit, - n_trials=100, - ) - - # then - # NOTE: these ranges params were the widest apart in many rounds of testing. - # Due to the stochastic nature of the tuning process, this test might fail. - # If it does, and you're sure the functions are all working, increase the range - # on these numbers with the new, failed value and re-run - assert 10 <= optimal_params["teleportation_threshold"] <= 70 - assert 1 <= optimal_params["teleportation_distance"] <= 7 - assert 5 <= optimal_params["min_neighbors"] <= 11 - assert 10064 <= optimal_params["max_num_neighbors_to_search"] <= 98798 - assert ( - optimal_params["decomposition_strategy"] == 0 - or optimal_params["decomposition_strategy"] == 1 - ) - - -@SKIP_SLOW -def test_get_optimal_hyperparams_for_time(large_circuit): - # when - optimal_params = get_optimal_hyperparams_for_time( - rbs_iteration_time=0.2, - max_allowed_time=0.8, - circuit=large_circuit, - n_trials=100, - ) - - # then - # NOTE: these ranges params were the widest apart in many rounds of testing. - # Due to the stochastic nature of the tuning process, this test might fail. - # If it does, and you're sure the functions are all working, increase the range - # on these numbers with the new, failed value and re-run - assert 26 <= optimal_params["teleportation_threshold"] <= 69 - assert 1 <= optimal_params["teleportation_distance"] <= 6 - assert 2 <= optimal_params["min_neighbors"] <= 11 - assert 10323 <= optimal_params["max_num_neighbors_to_search"] <= 97971 - assert ( - optimal_params["decomposition_strategy"] == 0 - or optimal_params["decomposition_strategy"] == 1 - ) - - -@SKIP_SLOW -def test_get_optimal_hyperparams_for_space_and_time(large_circuit): - # given/when - optimal_params = get_optimal_hyperparams_for_space_and_time( - rbs_iteration_time=0.2, - max_allowed_time=0.8, - circuit=large_circuit, - n_trials=100, - ) - - # then - # NOTE: these ranges params were the widest apart in many rounds of testing. - # Due to the stochastic nature of the tuning process, this test might fail. - # If it does, and you're sure the functions are all working, increase the range - # on these numbers with the new, failed value and re-run - assert 13 <= optimal_params["teleportation_threshold"] <= 70 - assert 1 <= optimal_params["teleportation_distance"] <= 7 - assert 3 <= optimal_params["min_neighbors"] <= 11 - assert 11991 <= optimal_params["max_num_neighbors_to_search"] <= 99154 - assert ( - optimal_params["decomposition_strategy"] == 0 - or optimal_params["decomposition_strategy"] == 1 - ) - - -@SKIP_SLOW -def test_get_optimal_hyperparams_for_estimated_rbs_time(large_circuit): - # when - optimal_params = get_optimal_hyperparams_for_estimated_rbs_time( - rbs_iteration_time=0.2, - circuit=large_circuit, - n_trials=100, - ) - - # then - # NOTE: these ranges params were the widest apart in many rounds of testing. - # Due to the stochastic nature of the tuning process, this test might fail. - # If it does, and you're sure the functions are all working, increase the range - # on these numbers with the new, failed value and re-run - assert 16 <= optimal_params["teleportation_threshold"] <= 70 - assert 1 <= optimal_params["teleportation_distance"] <= 7 - assert 2 <= optimal_params["min_neighbors"] <= 11 - assert 19544 <= optimal_params["max_num_neighbors_to_search"] <= 91836 - assert ( - optimal_params["decomposition_strategy"] == 0 - or optimal_params["decomposition_strategy"] == 1 - ) diff --git a/tests/benchq/compilation/test_rbs_with_pauli_tracking.py b/tests/benchq/compilation/test_rbs_with_pauli_tracking.py new file mode 100644 index 00000000..b8ae2bc2 --- /dev/null +++ b/tests/benchq/compilation/test_rbs_with_pauli_tracking.py @@ -0,0 +1,574 @@ +#!/usr/bin/env python +import os +import random + +import numpy as np +import pytest +import qiskit +from orquestra.quantum.circuits import CNOT, CZ, RZ, Circuit, H, I, S, T, X, Y, Z +from qiskit import Aer, ClassicalRegister, QuantumCircuit, QuantumRegister +from qiskit.transpiler.passes import RemoveBarriers + +from benchq.compilation.graph_states import jl +from benchq.conversions import export_circuit +from benchq.visualization_tools.plot_graph_state import plot_graph_state + +np.random.seed(0) +random.seed(0) + +SKIP_SLOW = pytest.mark.skipif( + os.getenv("SLOW_BENCHMARKS") is None, + reason="Slow benchmarks can only run if SLOW_BENCHMARKS env variable is defined", +) + + +def verify_random_circuit(n_qubits, depth, hyperparams, optimization, verbose): + # test that a single random circuit works for |0> initialization + + circuit = generate_random_circuit(n_qubits, depth) + + check_correctness_for_single_init( + circuit, + # Initialize in all possible single qubit stabiilzer states + Circuit([H(0), H(1), H(2), H(3), H(4), H(5), S(3), S(4), S(5)]), + hyperparams, + show_circuit=True, + throw_error_on_incorrect_result=True, + optimization=optimization, + verbose=verbose, + ) + + +def generate_random_circuit(n_qubits, depth): + # Generate a random circuit, but make sure + ops = [I, X, Y, Z, H, S, RZ, T, T.dagger, CNOT, CZ] + + circuit = Circuit([]) + for gate in random.choices(ops, k=depth): + if gate in [CNOT, CZ]: + qubit_1, qubit_2 = random.sample(range(n_qubits), 2) + circuit += gate(qubit_1, qubit_2) + else: + qubit = random.choice(list(range(n_qubits))) + if gate == RZ: + circuit += gate(random.uniform(0, 2 * np.pi))(qubit) + else: + circuit += gate(qubit) + + return circuit + + +def check_correctness_for_single_init( + circuit, + init, + hyperparams, + show_circuit=False, + show_graph_state=False, + throw_error_on_incorrect_result=True, + optimization="Time", + max_num_qubits=3, + verbose=False, +): + full_circuit = init + circuit + + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + full_circuit, + verbose=verbose, + takes_graph_input=False, + gives_graph_output=False, + optimization=str(optimization), + max_num_qubits=max_num_qubits, + hyperparams=hyperparams, + ) + + print("Returned to Python!") + + asg, pauli_tracker = jl.python_asg(asg), jl.python_pauli_tracker(pauli_tracker) + + print("Converted to Python!") + + pdf = simulate(circuit, init, asg, pauli_tracker, show_circuit=show_circuit) + + print("Finished Simulation!") + + if show_graph_state: + plot_graph_state(asg, pauli_tracker) + + # Format the pdf for printing + binary_distribution = {} + n = len(pdf) + + all_bitstrings = [ + format(i, f"0{full_circuit.n_qubits}b") + for i in range(2**full_circuit.n_qubits) + ] + + for i in range(n): + binary_distribution[all_bitstrings[i]] = pdf[i] + reversed_prob_density = {} + for binary_str, probability in binary_distribution.items(): + reversed_binary_str = binary_str[::-1] # Reverse the binary string + reversed_prob_density[reversed_binary_str] = probability + + correct_pdf = { + bitstring: 1.0 if bitstring == "0" * full_circuit.n_qubits else 0.0 + for bitstring in all_bitstrings + } + if reversed_prob_density != correct_pdf: + print("\033[91m" + "Incorrect Result Detected!" + "\033[0m") + # remove trivial parts of pdf so it's easier to read + reversed_prob_density = { + k: v for k, v in reversed_prob_density.items() if v != 0 + } + print(f"circuit: {circuit},\ninit: {init} \npdf: {reversed_prob_density}") + if throw_error_on_incorrect_result: + raise Exception("Incorrect Result Detected!") + return circuit, init, reversed_prob_density + else: + print("\033[92m" + "Correct Result!" + "\033[0m") + return None + + +def simulate(circuit, init, asg, pauli_tracker, show_circuit=True): + creg = ClassicalRegister(asg["n_nodes"]) + reg = QuantumRegister(asg["n_nodes"]) + c = QuantumCircuit(reg, creg) + for i in range(asg["n_nodes"]): + c.h(reg[i]) + + c.barrier(label="graph") + for node, neighborhood in enumerate(asg["edge_data"]): + for neighbor in neighborhood: + if node < neighbor: # avoid duplicate edges + c.cz(reg[node], reg[neighbor]) + + c.barrier(label="SQC") + enact_sqc_layer(asg, c, reg) + + control_values = [True] * asg["n_nodes"] + node_measured = [False] * asg["n_nodes"] + + remaining_dag = [[[], []] for _ in range(asg["n_nodes"])] + # only include paulis which have an affect + for target, controls in enumerate(pauli_tracker["cond_paulis"]): + x_controls, z_controls = controls + for control in x_controls: + if ( + pauli_tracker["measurements"][target][0] != jl.I_code + or target in asg["data_nodes"] + ): + remaining_dag[target][0].append(control) + for control in z_controls: + if ( + pauli_tracker["measurements"][target][0] != jl.H_code + or target in asg["data_nodes"] + ): + remaining_dag[target][1].append(control) + + print("Creating layering in simulation!") + + all_nodes = list(range(asg["n_nodes"])) + + for layer_label, layer in enumerate(pauli_tracker["layering"]): + c.barrier(label=f"Layer:{layer_label}") + for node in layer: + # the last frame always contains the data nodes, so we can skip them here + if node in asg["data_nodes"]: + continue + + measure_node(node, pauli_tracker, c, creg) + node_measured[node] = True + + c.barrier(label=f"Paulis:{layer_label}") + # repeat many times to ensure that all possible paulis are enacted + for _ in range(100): + for control in all_nodes: + # enact paulis which are controlled by that measurement + for target, controls in enumerate(remaining_dag): + x_controls, z_controls = controls + if node_measured[control]: + control_basis = int(pauli_tracker["measurements"][control][0]) + target_basis = int(pauli_tracker["measurements"][target][0]) + + # In the control is blocked by a non-clifford measurement, + # we can't enact the Pauli yet. + if ( + remaining_dag[control][0] == [] + and control_basis in jl.non_clifford_gate_codes + ) or control_basis != jl.non_clifford_gate_codes: + enact_controlled_paulis( + x_controls, + z_controls, + remaining_dag, + control, + target, + control_values, + asg, + c, + creg, + node_measured, + target_basis, + ) + + c.barrier(label="inv circ") + c &= get_reversed_qiskit_circuit(circuit, asg["data_nodes"]) + + c.barrier(label="inv init") + c &= get_reversed_qiskit_circuit(init, asg["data_nodes"]) + + c.barrier(label="output") + for node in asg["data_nodes"]: + c.measure(reg[node], creg[node]) + + if show_circuit: + print(c) + + print("Starting simulation!") + simulator = Aer.get_backend("aer_simulator_matrix_product_state") + cc = qiskit.transpile(RemoveBarriers()(c), backend=simulator, optimization_level=3) + result = simulator.run(cc, shots=1000).result().get_counts() + + return counts_to_pdf(asg["data_nodes"], result) + + +def reverse_dag(dag): + reversed_dag = [[[], []] for _ in range(len(dag))] + for node, controls in enumerate(dag): + x_controls, z_controls = controls + for control in x_controls: + reversed_dag[control][0].append(node) + for control in z_controls: + reversed_dag[control][1].append(node) + return reversed_dag + + +def enact_sqc_layer(asg, c, reg): + for node, sqs in enumerate(asg["sqs"]): + if sqs == jl.I_code: + pass + elif sqs == jl.S_code: + c.s(reg[node]) + elif sqs == jl.H_code: + c.h(reg[node]) + elif sqs == jl.HSH_code: + c.h(reg[node]) + c.s(reg[node]) + c.h(reg[node]) + elif sqs == jl.SH_code: + c.h(reg[node]) + c.s(reg[node]) + elif sqs == jl.HS_code: + c.s(reg[node]) + c.h(reg[node]) + else: + raise Exception(f"other sqs: {sqs}") + + for node, pauli in enumerate(asg["sqp"]): + if pauli == jl.I_code: + pass + elif pauli == jl.X_code_internal: + c.x(reg[node]) + elif pauli == jl.Y_code_internal: + c.y(reg[node]) + elif pauli == jl.Z_code_internal: + c.z(reg[node]) + else: + raise Exception(f"other pauli: {pauli}") + + +def measure_node(node, pauli_tracker, c, creg): + if pauli_tracker["measurements"][node][0] == jl.I_code: + pass + elif pauli_tracker["measurements"][node][0] == jl.H_code: + c.h(node) + elif pauli_tracker["measurements"][node][0] == jl.T_code: + c.t(node) + elif pauli_tracker["measurements"][node][0] == jl.T_Dagger_code: + c.tdg(node) + elif pauli_tracker["measurements"][node][0] == jl.RZ_code: + c.rz(pauli_tracker["measurements"][node][1], node) + else: + measurement = pauli_tracker["measurements"][node][0] + raise Exception(f"Unknown measurement type: {measurement}") + + c.h(node) + c.measure(node, creg[node]) + + +def enact_controlled_paulis( + x_controls, + z_controls, + remaining_dag, + control, + target, + control_values, + asg, + c, + creg, + node_measured, + target_basis, +): + if control in x_controls: + remaining_dag[target][0].remove(control) + if target in asg["data_nodes"]: + c.x(target).c_if(control, control_values[control]) + else: + if target_basis in jl.non_clifford_gate_codes: + c.x(target).c_if(control, control_values[control]) + if target_basis == jl.H_code: + if node_measured[target]: + c.x(target).c_if(control, control_values[control]) + c.measure(target, creg[target]) + else: + c.x(target).c_if(control, control_values[control]) + if control in z_controls: + remaining_dag[target][1].remove(control) + if ( + target_basis == jl.I_code + or target_basis in jl.non_clifford_gate_codes + or target in asg["data_nodes"] + ): + if node_measured[target]: + c.x(target).c_if(control, control_values[control]) + c.measure(target, creg[target]) + else: + c.z(target).c_if(control, control_values[control]) + + +def get_reversed_qiskit_circuit(circuit, data_qubits): + shifted_orquestra_circuit = Circuit([]) + for op in circuit.inverse()._operations: + shifted_qubits = (data_qubits[index] for index in op.qubit_indices) + shifted_orquestra_circuit += op.gate(*shifted_qubits) + + return export_circuit(QuantumCircuit, shifted_orquestra_circuit) + + +# transformed the counts from the qiskit simulation into a real pdf; some really ugly +# bit shifting (and similar) is necessary here +def counts_to_pdf(bits, counts): + num_bits = len(bits) + pdf = np.zeros(2**num_bits, dtype=np.int_) + masks = [] + for i, _ in enumerate(pdf): + bit = 0 + for j, b in enumerate(bits): + bit += (i & 2**j) << (b - j) + masks.append(bit) + masks.reverse() + for e in counts: + found = False + for i, mask in enumerate(masks): + if (int(e, 2) & mask) == mask: + pdf[2**num_bits - 1 - i] += counts[e] + found = True + break + if not found: + raise Exception(f"no mask found for {e}") + pdf = pdf / float(np.sum(pdf)) + return pdf + + +def topological_sort(layer, cond_paulis): + visited = set() + result = [] + + def dfs(node): + visited.add(node) + for neighbor in cond_paulis[node][0] + cond_paulis[node][1]: + if neighbor not in visited and neighbor in layer: + dfs(neighbor) + result.append(node) + + for node in layer: + if node not in visited: + dfs(node) + + return result + + +@pytest.mark.parametrize("optimization", ["Space", "Time", "Variable"]) +@pytest.mark.parametrize( + "init", + [ + # All start in Z basis + Circuit([]), + # Some start in X basis, one in Z basis + Circuit([H(0), H(1)]), + # All start in X basis + Circuit([H(0), H(1), H(2)]), + # all start in Y basis + Circuit([H(0), S(0), H(1), S(1), H(2), S(2)]), + ], +) +@pytest.mark.parametrize( + "circuit", + [ + # T gates work alone + Circuit([T(0), T(0)]), + # rotations work alone + Circuit([RZ(2.44)(0), RZ(5.71)(0)]), + # rotations work in circuit + Circuit([Z(0), Y(0), RZ(1.07)(2), X(1)]), + # Standard single qubit gates + Circuit([X(0)]), + Circuit([H(0)]), + Circuit([S(0)]), + Circuit([H(0), S(0), H(0)]), + Circuit([H(0), S(0)]), + Circuit([S(0), H(0)]), + Circuit([H(2)]), + Circuit([H(0), CNOT(0, 1)]), + Circuit([CZ(0, 1), H(2)]), + Circuit([H(0), S(0), CNOT(0, 1), H(2)]), + Circuit([CNOT(0, 1), CNOT(1, 2)]), + Circuit([H(0), RZ(0.034023)(0)]), + # Test pauli tracker layering + Circuit( + [ + H(0), + S(0), + H(1), + CZ(0, 1), + H(2), + CZ(1, 2), + ] + ), + Circuit( + [ + H(0), + H(1), + H(3), + CZ(0, 3), + CZ(1, 4), + H(3), + H(4), + CZ(3, 4), + ] + ), + Circuit( + [ + H(0), + H(1), + H(4), + T(1), + CZ(0, 4), + CNOT(1, 0), + H(1), + CNOT(3, 1), + T(1), + CNOT(4, 1), + T(4), + H(4), + T(4), + ] + ), + Circuit( + [ + H(3), + CZ(0, 2), + T(1), + H(1), + T(1), + T(1), + CNOT(0, 1), + CZ(1, 2), + CNOT(2, 1), + T(1), + ], + ), + # test layering with non-clifford dependencies + Circuit( + [ + T(0), + H(0), + T(0), + T(0), + H(0), + T(0), + ] + ), + ], +) +def test_particular_circuits_give_correct_results(circuit, init, optimization): + hyperparams = jl.RbSHyperparams(3, 2, 6, 1e5, 0) + check_correctness_for_single_init( + circuit, + init, + hyperparams, + show_circuit=True, + throw_error_on_incorrect_result=True, + optimization=optimization, + max_num_qubits=3, + ) + + +# If you run this test, it will take a long time to complete. Make sure to +# run it with the -s option so that you can see the circuits being printed +# as well as the progress of the test. +@SKIP_SLOW +def test_1000_large_random_circuits(): + for n_circuits_checked in range(1000): + # randomize hyperparams + teleportation_threshold = np.random.randint(1, 10) + teleportation_depth = np.random.randint(1, 3) * 2 + min_neighbor_degree = np.random.randint(5, 20) + hyperparams = jl.RbSHyperparams( + teleportation_threshold, teleportation_depth, min_neighbor_degree, 1e5, 0 + ) + + optimization = np.random.choice(["Space", "Time", "Variable"]) + + print( + "\033[92m" + + f"{n_circuits_checked} circuits checked successfully!" + + "\033[0m" + ) + verify_random_circuit( + n_qubits=10, + depth=30, + hyperparams=hyperparams, + optimization=optimization, + verbose=True, + ) + n_circuits_checked += 1 + + +# leaving this here because it is useful for quickly debugging a circuit +# if __name__ == "__main__": +# # Eliminate unneeded gates quickly from examples +# ops = [] +# for _ in range(1000): +# to_remove = np.random.randint(0, len(ops)) +# new_ops = ops[:to_remove] + ops[to_remove + 1 :] +# try: +# check_correctness_for_single_init( +# Circuit(ops), +# Circuit([]), +# jl.RbSHyperparams(6, 4, 15, 1e5, 0), +# show_circuit=False, +# show_graph_state=False, +# throw_error_on_incorrect_result=True, +# optimization="Time", +# max_num_qubits=3, +# ) +# except Exception: +# ops = new_ops + +# print(Circuit(ops)) + +# # For more meticulous debugging, use this +# check_correctness_for_single_init( +# Circuit( +# [], +# ), +# Circuit([]), +# jl.RbSHyperparams(60, 4, 15, 1e5, 0), +# show_circuit=True, +# show_graph_state=False, +# throw_error_on_incorrect_result=True, +# optimization="Time", +# max_num_qubits=3, +# ) +# # stops evaluation on a correct result so you dont have to run it twice +# breakpoint() diff --git a/tests/benchq/compilation/test_ruby_slippers.py b/tests/benchq/compilation/test_ruby_slippers.py index ec486140..9aa301c4 100644 --- a/tests/benchq/compilation/test_ruby_slippers.py +++ b/tests/benchq/compilation/test_ruby_slippers.py @@ -2,6 +2,7 @@ # © Copyright 2022-2023 Zapata Computing Inc. ################################################################################ import os +import pathlib import networkx as nx import numpy as np @@ -12,13 +13,18 @@ from orquestra.quantum.circuits import CNOT, CZ, Circuit, H, S, T, X from qiskit import QuantumCircuit -from benchq.compilation import ( - jl, +from benchq.compilation.circuits import ( + compile_to_native_gates, pyliqtr_transpile_to_clifford_t, - transpile_to_native_gates, ) +from benchq.compilation.graph_states import jl from benchq.problem_embeddings.quantum_program import QuantumProgram +SKIP_SLOW = pytest.mark.skipif( + os.getenv("SLOW_BENCHMARKS") is None, + reason="Slow benchmarks can only run if SLOW_BENCHMARKS env variable is defined", +) + @pytest.mark.parametrize( "circuit", @@ -62,17 +68,74 @@ def test_stabilizer_states_are_the_same_for_simple_circuits(circuit): target_tableau = get_target_tableau(circuit) - loc, adj, _ = jl.run_ruby_slippers(circuit, False, 999) + hyperparams = jl.RbSHyperparams( + jl.UInt16(999), jl.UInt8(4), jl.UInt8(6), jl.UInt32(1e5), jl.UInt8(0) + ) + + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + circuit, + verbose=False, + takes_graph_input=False, + gives_graph_output=False, + optimization="Time", + hyperparams=hyperparams, + ) + num_logical_qubits = jl.get_num_logical_qubits(pauli_tracker.layering, asg, "Time") - vertices = list(zip(loc, adj)) + asg = jl.python_asg(asg) + pauli_tracker = jl.python_pauli_tracker(pauli_tracker) + vertices = list(zip(asg["sqs"], asg["edge_data"])) graph_tableau = get_stabilizer_tableau_from_vertices(vertices) + assert len(pauli_tracker["layering"]) == 1 + assert num_logical_qubits == circuit.n_qubits assert_tableaus_correspond_to_the_same_stabilizer_state( graph_tableau, target_tableau ) +@pytest.mark.parametrize( + "circuit, target_non_clifford_layers, target_qubits, optimization, max_num_qubits", + [ + (Circuit([H(0)] + [CNOT(0, i) for i in range(4)]), 1, 4, "Time", -1), + (Circuit([H(0)] + [CNOT(0, i) for i in range(4)]), 3, 2, "Space", -1), + (Circuit([H(0)] + [CNOT(0, i) for i in range(4)]), 3, 2, "Variable", 2), + (Circuit([H(0), T(0)] * 3), 3, 3, "Time", -1), + (Circuit([H(0), T(0)] * 3), 3, 2, "Space", -1), + (Circuit([H(0), T(0)] * 3), 3, 2, "Variable", 2), + ], +) +def test_tocks_layers_and_qubits_are_correct( + circuit, + target_non_clifford_layers, + target_qubits, + optimization, + max_num_qubits, +): + hyperparams = jl.RbSHyperparams( + jl.UInt16(999), jl.UInt8(4), jl.UInt8(6), jl.UInt32(1e5), jl.UInt8(0) + ) + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + circuit, + verbose=False, + takes_graph_input=False, + gives_graph_output=False, + optimization=optimization, + hyperparams=hyperparams, + max_num_qubits=max_num_qubits, + ) + num_logical_qubits = jl.get_num_logical_qubits( + pauli_tracker.layering, asg, optimization + ) + + asg = jl.python_asg(asg) + pauli_tracker = jl.python_pauli_tracker(pauli_tracker) + + assert len(pauli_tracker["layering"]) == target_non_clifford_layers + assert num_logical_qubits == target_qubits + + @pytest.mark.parametrize( "filename", [ @@ -89,13 +152,25 @@ def test_stabilizer_states_are_the_same_for_circuits(filename): QuantumCircuit.from_qasm_file(os.path.join("examples", "data", filename)) ) - circuit = transpile_to_native_gates(qiskit_circuit) + circuit = compile_to_native_gates(qiskit_circuit) test_circuit = get_icm(circuit) target_tableau = get_target_tableau(test_circuit) - loc, adj, _ = jl.run_ruby_slippers(test_circuit, False, 999) - vertices = list(zip(loc, adj)) + hyperparams = jl.RbSHyperparams( + jl.UInt16(999), jl.UInt8(4), jl.UInt8(6), jl.UInt32(1e5), jl.UInt8(0) + ) + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + circuit, + verbose=False, + takes_graph_input=False, + gives_graph_output=False, + optimization="Time", + hyperparams=hyperparams, + ) + asg = jl.python_asg(asg) + + vertices = list(zip(asg["sqs"], asg["edge_data"])) graph_tableau = get_stabilizer_tableau_from_vertices(vertices) assert_tableaus_correspond_to_the_same_stabilizer_state( @@ -103,6 +178,7 @@ def test_stabilizer_states_are_the_same_for_circuits(filename): ) +@SKIP_SLOW @pytest.mark.parametrize( "filename", [ @@ -129,12 +205,24 @@ def test_stabilizer_states_are_the_same_for_circuits_with_decomposed_rotations( qiskit_circuit, circuit_precision=10**-2 ) test_circuit = get_icm(clifford_t) + test_circuit = compile_to_native_gates(test_circuit) target_tableau = get_target_tableau(test_circuit) # ensure state does not teleport - loc, adj, _ = jl.run_ruby_slippers(test_circuit, True, 9999, 9999) - vertices = list(zip(loc, adj)) + hyperparams = jl.RbSHyperparams( + jl.UInt16(999), jl.UInt8(4), jl.UInt8(6), jl.UInt32(1e5), jl.UInt8(0) + ) + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + test_circuit, + verbose=False, + takes_graph_input=False, + gives_graph_output=False, + optimization="Time", + hyperparams=hyperparams, + ) + asg = jl.python_asg(asg) + vertices = list(zip(asg["sqs"], asg["edge_data"])) graph_tableau = get_stabilizer_tableau_from_vertices(vertices) @@ -164,15 +252,17 @@ def test_stabilizer_states_are_the_same_for_circuits_with_decomposed_rotations( (Circuit([H(0), *[CNOT(0, i) for i in range(1, 15)]]), 4, 4, 4), # test gates that must be decomposed (Circuit([H(0), *[T(0) for _ in range(1, 5)]]), 4, 4, 0), - # test single teleporatation - (Circuit([H(0), *[T(0) for _ in range(1, 6)]]), 4, 4, 1), - (Circuit([H(0), *[T(0) for _ in range(1, 8)]]), 4, 4, 1), - # test multiple teleportations: - (Circuit([H(0), *[T(0) for _ in range(1, 9)]]), 4, 4, 2), - (Circuit([H(0), *[T(0) for _ in range(1, 11)]]), 4, 4, 2), - (Circuit([H(0), *[T(0) for _ in range(1, 12)]]), 4, 4, 3), - (Circuit([H(0), *[T(0) for _ in range(1, 14)]]), 4, 4, 3), - (Circuit([H(0), *[T(0) for _ in range(1, 15)]]), 4, 4, 4), + # commenting out these test for now as they are only relevant for + # decomposition strategy 1. + # # test single teleporatation + # (Circuit([H(0), *[T(0) for _ in range(1, 6)]]), 4, 4, 1), + # (Circuit([H(0), *[T(0) for _ in range(1, 8)]]), 4, 4, 1), + # # test multiple teleportations with gates that must be decomposed + # (Circuit([H(0), *[T(0) for _ in range(1, 9)]]), 4, 4, 2), + # (Circuit([H(0), *[T(0) for _ in range(1, 11)]]), 4, 4, 2), + # (Circuit([H(0), *[T(0) for _ in range(1, 12)]]), 4, 4, 3), + # (Circuit([H(0), *[T(0) for _ in range(1, 14)]]), 4, 4, 3), + # (Circuit([H(0), *[T(0) for _ in range(1, 15)]]), 4, 4, 4), ], ) def test_teleportation_produces_correct_number_of_nodes_for_small_circuits( @@ -182,18 +272,24 @@ def test_teleportation_produces_correct_number_of_nodes_for_small_circuits( n_t_gates = quantum_program.n_t_gates n_rotations = quantum_program.n_rotation_gates - loc, adj, _ = jl.run_ruby_slippers( + hyperparams = jl.RbSHyperparams( + jl.UInt16(teleportation_threshold), + jl.UInt8(teleportation_distance), + jl.UInt8(6), + jl.UInt32(1e5), + jl.UInt8(0), + ) + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( circuit, - True, - 9999, - teleportation_threshold, - teleportation_distance, - 6, - 99999, - 1, + verbose=False, + takes_graph_input=False, + gives_graph_output=False, + optimization="Time", + hyperparams=hyperparams, ) + asg = jl.python_asg(asg) - n_nodes = len(loc) + n_nodes = len(asg["sqp"]) assert ( n_nodes @@ -232,15 +328,28 @@ def test_teleportation_produces_correct_node_parity_for_large_circuits( quantum_program = QuantumProgram.from_circuit(clifford_t) n_t_gates = quantum_program.n_t_gates - loc, adj, _ = jl.run_ruby_slippers(clifford_t, False, 9999) + # set threshold low so we teleport many times + hyperparams = jl.RbSHyperparams( + jl.UInt16(3), jl.UInt8(4), jl.UInt8(6), jl.UInt32(1e5), jl.UInt8(0) + ) + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + clifford_t, + verbose=False, + takes_graph_input=False, + gives_graph_output=False, + optimization="Time", + hyperparams=hyperparams, + ) + asg = jl.python_asg(asg) - n_nodes = len(loc) + n_nodes = len(asg["sqp"]) assert n_nodes >= n_t_gates # teleportation only adds 2 nodes at a time. - assert (n_nodes - n_t_gates) % 2 == 0 + assert (n_nodes - n_t_gates - clifford_t.n_qubits) % 2 == 0 +@pytest.mark.skip(reason="This test requires hyperparameter tuning.") @pytest.mark.parametrize( "circuit, rbs_iteration_time, expected_prop_range", [ @@ -257,7 +366,14 @@ def test_teleportation_produces_correct_node_parity_for_large_circuits( def test_rbs_gives_reasonable_prop(circuit, rbs_iteration_time, expected_prop_range): # when _, _, prop = jl.run_ruby_slippers( - circuit, True, 9999, 40, 4, 6, 99999, 1, rbs_iteration_time + circuit, + takes_graph_input=False, + gives_graph_output=False, + verbose=True, + max_graph_size=9999, + teleportation_threshold=40, + teleportation_distance=9, + max_time=rbs_iteration_time, ) # then diff --git a/tests/benchq/compilation/test_transpile_to_native_gates.py b/tests/benchq/compilation/test_transpile_to_native_gates.py index b9f58ed5..6f609669 100644 --- a/tests/benchq/compilation/test_transpile_to_native_gates.py +++ b/tests/benchq/compilation/test_transpile_to_native_gates.py @@ -18,7 +18,7 @@ Z, ) -from benchq.compilation import transpile_to_native_gates +from benchq.compilation.circuits import compile_to_native_gates TOFFOLI_DECOMPOSITION = [ H(2), @@ -102,7 +102,7 @@ ], ) def test_simplify_rotation_handles_rotation_gates(input_circuit, output_circuit): - simplified_circuit = transpile_to_native_gates(input_circuit) + simplified_circuit = compile_to_native_gates(input_circuit) assert simplified_circuit == output_circuit @@ -123,7 +123,7 @@ def test_simplify_rotation_handles_rotation_gates(input_circuit, output_circuit) def test_simplify_rotation_handles_special_angles(angle, output_gates): qubit_id = 0 circuit = Circuit([RZ(angle)(qubit_id)]) - simplified_circuit = transpile_to_native_gates(circuit) + simplified_circuit = compile_to_native_gates(circuit) assert simplified_circuit == Circuit( [output_gate(qubit_id) for output_gate in output_gates] ) diff --git a/tests/benchq/decoder_modeling/test_decoder_resource_estimator.py b/tests/benchq/decoder_modeling/test_decoder_resource_estimator.py index 524c8f35..f6586709 100644 --- a/tests/benchq/decoder_modeling/test_decoder_resource_estimator.py +++ b/tests/benchq/decoder_modeling/test_decoder_resource_estimator.py @@ -24,7 +24,7 @@ def test_none_decoder_model_returns_non_decoder_info(): (17, "the decoder is too slow", "decoder_test_data_speed_limited"), ( 32, - "resource estimates have not been calculated", + "decoder properties have not been calculated", "decoder_test_data_size_limited", ), ], diff --git a/tests/benchq/examples/test_examples.py b/tests/benchq/examples/test_examples.py index ad77de1e..29495fd7 100644 --- a/tests/benchq/examples/test_examples.py +++ b/tests/benchq/examples/test_examples.py @@ -8,20 +8,20 @@ from orquestra.sdk.schema.workflow_run import State from qiskit.circuit import QuantumCircuit -from benchq.algorithms.data_structures import ( - AlgorithmImplementation, - ErrorBudget, - GraphPartition, +from benchq.algorithms.data_structures import AlgorithmImplementation, ErrorBudget +from benchq.compilation.circuits import pyliqtr_transpile_to_clifford_t +from benchq.compilation.graph_states import ( + get_implementation_compiler, + get_jabalizer_circuit_compiler, + jl, ) -from benchq.compilation import ( - get_algorithmic_graph_from_Jabalizer, - pyliqtr_transpile_to_clifford_t, +from benchq.compilation.graph_states.substrate_scheduler.python_substrate_scheduler import ( # noqa: E501 + python_substrate_scheduler, ) -from benchq.magic_state_distillation.litinski_factories import iter_litinski_factories -from benchq.problem_embeddings.quantum_program import QuantumProgram +from benchq.conversions import import_circuit from benchq.quantum_hardware_modeling import BASIC_SC_ARCHITECTURE_MODEL from benchq.resource_estimators.default_estimators import get_precise_graph_estimate -from benchq.resource_estimators.graph_estimators import GraphResourceEstimator +from benchq.resource_estimators.graph_estimator import GraphResourceEstimator MAIN_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.insert(0, os.path.dirname(MAIN_DIR)) @@ -32,7 +32,7 @@ main as packages_comparison_main, ) from examples.ex_4_fast_graph_estimates import main as fast_graph # noqa: E402 -from examples.ex_11_utility_scale import main as utility_scale # noqa: E402 +from examples.ex_10_utility_scale import main as utility_scale # noqa: E402 SKIP_AZURE = pytest.mark.skipif( os.getenv("BENCHQ_TEST_AZURE") is None, @@ -77,84 +77,110 @@ def test_packages_comparison_example(): packages_comparison_main() -def test_extrapolation_example(): +def test_fast_graph_example(): fast_graph() def test_utility_scale_example(): decoder_data = os.path.join("examples", "data", "sample_decoder_data.csv") - gsc, footprint = utility_scale(decoder_data, False, "triangular", 3) + gsc, footprint = utility_scale(decoder_data, False, "triangular", 2) assert gsc assert footprint def test_toy_example_notebook(): """Test all of the lines in the toy model work.""" - file_path = os.path.join("examples", "data", "example_circuit.qasm") + file_path = os.path.join("examples", "data", "single_rotation.qasm") demo_circuit = QuantumCircuit.from_qasm_file(file_path) architecture_model = BASIC_SC_ARCHITECTURE_MODEL clifford_t_circuit = pyliqtr_transpile_to_clifford_t( - demo_circuit, circuit_precision=1e-6 + demo_circuit, circuit_precision=1e-2 ) - circuit_graph = get_algorithmic_graph_from_Jabalizer(clifford_t_circuit) + compiler = get_jabalizer_circuit_compiler() + optimization = "Time" # or "Space" + verbose = False + compiler(clifford_t_circuit, optimization, verbose) + + asg, pauli_tracker, _ = jl.get_rbs_graph_state_data( + clifford_t_circuit, + takes_graph_input=False, + gives_graph_output=False, + verbose=verbose, + optimization=optimization, + ) + asg = jl.python_asg(asg) + pauli_tracker = jl.python_pauli_tracker(pauli_tracker) - # only allow a failure to occur 1% of the time + # 1% error margin split evenly between all sources of error budget = ErrorBudget.from_even_split(1e-2) - program = GraphPartition( - QuantumProgram.from_circuit(clifford_t_circuit), [circuit_graph] + # Specify the circuit and the margins of error we allow in the results + implementation = AlgorithmImplementation.from_circuit( + clifford_t_circuit, budget, n_shots=1 ) - implementation = AlgorithmImplementation(program, budget, 1) - estimator = GraphResourceEstimator(architecture_model) - estimator.estimate(implementation) + # Specify how to run the circuit + estimator = GraphResourceEstimator(optimization, verbose) + + # Modify our compiler to compile AlgorithmImplementation objects rather than + # just circuits + implementation_compiler = get_implementation_compiler(compiler) + + # run the estimator + estimator.compile_and_estimate( + implementation, implementation_compiler, architecture_model + ) # only allow a failure to occur 1% of the time budget = ErrorBudget.from_even_split(1e-2) implementation = AlgorithmImplementation.from_circuit(demo_circuit, budget, 1) - get_precise_graph_estimate(implementation, architecture_model) + optimization = "Time" + get_precise_graph_estimate(implementation, architecture_model, optimization) - get_algorithmic_graph_from_Jabalizer(clifford_t_circuit) + compiler(clifford_t_circuit, optimization="Time", verbose=True) get_icm(clifford_t_circuit) - graph_partition = GraphPartition(program, [circuit_graph]) + asg, _, __ = jl.get_rbs_graph_state_data( + clifford_t_circuit, + takes_graph_input=False, + gives_graph_output=False, + verbose=False, + ) + asg = jl.python_asg(asg) - graph_data = estimator._get_graph_data_for_single_graph(graph_partition) + compiled_implementation = implementation_compiler(implementation, optimization) + compiled_implementation.program.subroutines[0] - magic_state_factory = iter_litinski_factories(architecture_model)[0] + estimator.estimate_resources_from_compiled_implementation( + compiled_implementation, + architecture_model, + ) - len(circuit_graph) + schedule = python_substrate_scheduler(asg, "fast") - n_total_t_gates = estimator.get_n_total_t_gates( - graph_data.n_t_gates, - graph_data.n_rotation_gates, - budget.transpilation_failure_tolerance, - ) + [[node[0] for node in step] for step in schedule.measurement_steps] - distance = estimator._minimize_code_distance( - n_total_t_gates, - graph_data, - architecture_model.physical_qubit_error_rate, # physical error - magic_state_factory, - ) - estimator._get_n_physical_qubits(graph_data, distance, magic_state_factory) - estimator._get_time_per_circuit_in_seconds( - graph_data, distance, n_total_t_gates, magic_state_factory - ) + file_path = os.path.join("examples", "data", "ghz_circuit.qasm") + ghz_circuit = import_circuit(QuantumCircuit.from_qasm_file(file_path)) - from benchq.resource_estimators.graph_estimators.graph_estimator import ( - substrate_scheduler, + asg, _, __ = jl.get_rbs_graph_state_data( + ghz_circuit, takes_graph_input=False, gives_graph_output=False, verbose=False ) + asg = jl.python_asg(asg) - compiler = substrate_scheduler(circuit_graph, "fast") - [[node[0] for node in step] for step in compiler.measurement_steps] + schedule = python_substrate_scheduler(asg, "fast") - circuit = QuantumCircuit.from_qasm_file(file_path) + file_path = os.path.join("examples", "data", "h_chain_circuit.qasm") + h_chain_circuit = import_circuit(QuantumCircuit.from_qasm_file(file_path)) - clifford_t_circuit = pyliqtr_transpile_to_clifford_t( - circuit, circuit_precision=1e-10 + asg, _, __ = jl.get_rbs_graph_state_data( + h_chain_circuit, + takes_graph_input=False, + gives_graph_output=False, + verbose=False, ) - circuit_graph = get_algorithmic_graph_from_Jabalizer(clifford_t_circuit) - substrate_scheduler(circuit_graph, "fast") + asg = jl.python_asg(asg) + + schedule = python_substrate_scheduler(asg, "fast") diff --git a/tests/benchq/magic_state_distillation/test_autoccz_factories.py b/tests/benchq/magic_state_distillation/test_autoccz_factories.py index fad5e371..4944ac91 100644 --- a/tests/benchq/magic_state_distillation/test_autoccz_factories.py +++ b/tests/benchq/magic_state_distillation/test_autoccz_factories.py @@ -7,4 +7,4 @@ def test_factory_properties_are_correct(): assert factory.distilled_magic_state_error_rate < 1e-4 assert factory.qubits > 0 assert factory.distillation_time_in_cycles > 0 - assert factory.n_t_gates_produced_per_distillation == 2 + assert factory.t_gates_per_distillation == 2 diff --git a/tests/benchq/magic_state_distillation/test_litinski_factories.py b/tests/benchq/magic_state_distillation/test_litinski_factories.py index a04fdab2..b898104f 100644 --- a/tests/benchq/magic_state_distillation/test_litinski_factories.py +++ b/tests/benchq/magic_state_distillation/test_litinski_factories.py @@ -27,7 +27,7 @@ def test_factory_properties_are_correct(architecture_model): ) assert factory.qubits > 0 assert factory.distillation_time_in_cycles > 0 - assert factory.n_t_gates_produced_per_distillation >= 1 + assert factory.t_gates_per_distillation >= 1 def test_factory_based_on_err_rate(): diff --git a/tests/benchq/mlflow/test_data_logging.py b/tests/benchq/mlflow/test_data_logging.py index 90f5b89d..02b75981 100644 --- a/tests/benchq/mlflow/test_data_logging.py +++ b/tests/benchq/mlflow/test_data_logging.py @@ -34,7 +34,7 @@ "code_distance": 19, "decoder_info": None, "extra": { - "max_graph_degree": 51, + "num_logical_qubits": 51, "n_measurement_steps": 81, "n_nodes": 1550, "n_rotation_gates": 0, @@ -49,7 +49,7 @@ { "code_distance": 19, "decoder_info": None, - "extra.max_graph_degree": 51, + "extra.num_logical_qubits": 51, "extra.n_measurement_steps": 81, "extra.n_nodes": 1550, "extra.n_rotation_gates": 0, @@ -111,9 +111,9 @@ def test_log_resource_info_to_mlflow(mock_mlflow): logical_error_rate=0.1, n_logical_qubits=1, n_physical_qubits=1, - routing_to_measurement_volume_ratio=1, total_time_in_seconds=0.01, decoder_info=None, + optimization="gamma", magic_state_factory_name="tau", extra=None, ) diff --git a/tests/benchq/problem_embeddings/test_qaoa.py b/tests/benchq/problem_embeddings/test_qaoa.py index d13c9a22..2f168b0e 100644 --- a/tests/benchq/problem_embeddings/test_qaoa.py +++ b/tests/benchq/problem_embeddings/test_qaoa.py @@ -5,7 +5,7 @@ from orquestra.quantum.circuits import Circuit from orquestra.quantum.operators import PauliSum, PauliTerm -from benchq.problem_embeddings._qaoa import get_qaoa_circuit +from benchq.problem_embeddings.qaoa._qaoa import get_qaoa_circuit def test_get_qaoa_circuit_produces_correct_output_for_small_coefficeints(): diff --git a/tests/benchq/problem_embeddings/test_qpe.py b/tests/benchq/problem_embeddings/test_qpe.py index b61744db..ce1f856d 100644 --- a/tests/benchq/problem_embeddings/test_qpe.py +++ b/tests/benchq/problem_embeddings/test_qpe.py @@ -27,9 +27,7 @@ get_hydrogen_chain_hamiltonian_generator, ) from benchq.quantum_hardware_modeling import BasicArchitectureModel -from benchq.resource_estimators.footprint_estimators.openfermion_estimator import ( - footprint_estimator, -) +from benchq.resource_estimators.openfermion_estimator import openfermion_estimator @pytest.mark.parametrize( @@ -105,7 +103,7 @@ def test_physical_qubits_larger_than_logical_qubits(): BAM.physical_qubit_error_rate = 1.0e-4 BAM.surface_code_cycle_time_in_seconds = 1e-7 - resource_estimate = footprint_estimator( + resource_estimate = openfermion_estimator( num_toffoli=n_toffoli, num_logical_qubits=n_logical_qubits, architecture_model=BAM, @@ -132,7 +130,7 @@ def test_monotonicity_of_duration_wrt_scc_time(scc_time_low, scc_time_high): BAM_fast = BasicArchitectureModel BAM_fast.physical_qubit_error_rate = 1.0e-4 BAM_fast.surface_code_cycle_time_in_seconds = scc_time_low - resource_estimates_low = footprint_estimator( + resource_estimates_low = openfermion_estimator( num_toffoli=n_toffoli, num_logical_qubits=n_logical_qubits, architecture_model=BAM_fast, @@ -141,7 +139,7 @@ def test_monotonicity_of_duration_wrt_scc_time(scc_time_low, scc_time_high): BAM_slow = BasicArchitectureModel BAM_slow.physical_qubit_error_rate = 1.0e-4 BAM_slow.surface_code_cycle_time_in_seconds = scc_time_high - resource_estimates_high = footprint_estimator( + resource_estimates_high = openfermion_estimator( num_toffoli=n_toffoli, num_logical_qubits=n_logical_qubits, architecture_model=BAM_slow, @@ -174,7 +172,7 @@ def test_linearity_of_duration_wrt_scc_time(scc_time_low, scc_time_high): BAM_fast.physical_qubit_error_rate = 1.0e-4 BAM_fast.surface_code_cycle_time_in_seconds = scc_time_low - resource_estimates_low = footprint_estimator( + resource_estimates_low = openfermion_estimator( num_toffoli=n_toffoli, num_logical_qubits=n_logical_qubits, architecture_model=BAM_fast, @@ -183,7 +181,7 @@ def test_linearity_of_duration_wrt_scc_time(scc_time_low, scc_time_high): BAM_slow = BasicArchitectureModel BAM_slow.physical_qubit_error_rate = 1.0e-4 BAM_slow.surface_code_cycle_time_in_seconds = scc_time_high - resource_estimates_high = footprint_estimator( + resource_estimates_high = openfermion_estimator( num_toffoli=n_toffoli, num_logical_qubits=n_logical_qubits, architecture_model=BAM_slow, @@ -216,13 +214,13 @@ def test_ratio_of_failure_prob_of_magicstateFactory(num_toffoli, num_t): BAM.physical_qubit_error_rate = 1.0e-4 BAM.surface_code_cycle_time_in_seconds = 2e-6 - best_toffoli = footprint_estimator( + best_toffoli = openfermion_estimator( num_logical_qubits=num_logical_qubits, num_toffoli=num_toffoli, architecture_model=BAM, hardware_failure_tolerance=1e-1, ) - best_T = footprint_estimator( + best_T = openfermion_estimator( num_logical_qubits=num_logical_qubits, num_t=num_t, architecture_model=BAM, @@ -255,13 +253,13 @@ def test_calc_of_algorithm_failure_prob(n_toffoli, n_T): BAM = BasicArchitectureModel BAM.physical_qubit_error_rate = 1.0e-4 BAM.surface_code_cycle_time_in_seconds = 2e-6 - best_toffoli = footprint_estimator( + best_toffoli = openfermion_estimator( num_logical_qubits=num_logical_qubits, num_toffoli=n_toffoli, architecture_model=BAM, hardware_failure_tolerance=1e-1, ) - best_T = footprint_estimator( + best_T = openfermion_estimator( num_logical_qubits=num_logical_qubits, num_t=n_T, architecture_model=BAM, @@ -284,14 +282,14 @@ def test_algorithm_failure_prob_calculation(): BAM = BasicArchitectureModel BAM.physical_qubit_error_rate = 1.0e-4 BAM.surface_code_cycle_time_in_seconds = 2e-6 - best_cost_toffoli = footprint_estimator( + best_cost_toffoli = openfermion_estimator( num_logical_qubits=num_logical_qubits, num_toffoli=20, num_t=20, architecture_model=BAM, hardware_failure_tolerance=1e-1, ) - best_cost_t = footprint_estimator( + best_cost_t = openfermion_estimator( num_logical_qubits=num_logical_qubits, num_toffoli=30, num_t=0, @@ -316,7 +314,7 @@ def test_default_values(): BAM.physical_qubit_error_rate = 1.0e-4 BAM.surface_code_cycle_time_in_seconds = 2 * 1e-6 with pytest.raises(ValueError) as dvalue: - a, b = footprint_estimator( + a, b = openfermion_estimator( num_logical_qubits=num_logical_qubits, architecture_model=BAM, hardware_failure_tolerance=1e-1, @@ -334,7 +332,7 @@ def test_all_default_values(): """ num_logical_qubits = 12 with pytest.raises(ValueError) as dvalue: - footprint_estimator( + openfermion_estimator( num_logical_qubits=num_logical_qubits, hardware_failure_tolerance=1e-1, ) @@ -348,7 +346,7 @@ def test_default_scc_time(): This test will verify attributes of default Architecture Model i.e. BASIC_SC_ARCHITECTURE_MODEL """ - cost = footprint_estimator( + cost = openfermion_estimator( num_logical_qubits=num_logical_qubits, num_t=25, num_toffoli=25, @@ -358,10 +356,10 @@ def test_default_scc_time(): assert cost.extra.scc_time == 0.1e-6 -def test_footprint_estimator_supports_large_circuits(): +def test_openfermion_estimator_supports_large_circuits(): n_logical_qubits = 4e3 n_toffoli = 1e12 - resource_estimate = footprint_estimator( + resource_estimate = openfermion_estimator( n_logical_qubits, n_toffoli, hardware_failure_tolerance=1e-1 ) assert resource_estimate.n_physical_qubits > n_logical_qubits diff --git a/tests/benchq/quantum_hardware_modeling/test_hardware_architecture_models.py b/tests/benchq/quantum_hardware_modeling/test_hardware_architecture_models.py index 327e81b1..ce299752 100644 --- a/tests/benchq/quantum_hardware_modeling/test_hardware_architecture_models.py +++ b/tests/benchq/quantum_hardware_modeling/test_hardware_architecture_models.py @@ -17,9 +17,9 @@ def dummy_resource_info(): n_logical_qubits=30, n_physical_qubits=300, total_time_in_seconds=5, + optimization="", decoder_info=None, magic_state_factory_name="", - routing_to_measurement_volume_ratio=1, extra=None, ) yield resource_info diff --git a/tests/benchq/resource_estimation/graph_estimators/test_extrapolation_estimator.py b/tests/benchq/resource_estimation/graph_estimators/test_extrapolation_estimator.py deleted file mode 100644 index 968aacce..00000000 --- a/tests/benchq/resource_estimation/graph_estimators/test_extrapolation_estimator.py +++ /dev/null @@ -1,345 +0,0 @@ -from dataclasses import asdict, replace - -import numpy as np -import pytest -from orquestra.quantum.circuits import CNOT, RZ, Circuit, H - -from benchq.algorithms.data_structures import AlgorithmImplementation, ErrorBudget -from benchq.compilation import get_ruby_slippers_compiler -from benchq.problem_embeddings import QuantumProgram -from benchq.quantum_hardware_modeling.hardware_architecture_models import ( - BASIC_SC_ARCHITECTURE_MODEL, -) -from benchq.resource_estimators.graph_estimators import ( - ExtrapolationResourceEstimator, - GraphResourceEstimator, - create_big_graph_from_subcircuits, - get_custom_extrapolated_estimate, - get_custom_resource_estimation, - synthesize_clifford_t, - transpile_to_native_gates, -) - -# Below is code snippet for inspecting the extrapolations visually -# you can paste it directly into the terminal when a test fails with -# the python debugger. -# from benchq.vizualization_tools import plot_extrapolations -# plot_extrapolations(extrapolated_resource_estimates, steps_to_extrapolate_from, n_measurement_steps_fit_type, gsc_resource_estimates) # noqa: E501 - -fast_ruby_slippers = get_ruby_slippers_compiler( - teleportation_threshold=1e4, - max_graph_size=1e5, - decomposition_strategy=0, -) - - -@pytest.fixture(params=["time", "space"]) -def optimization(request): - return request.param - - -@pytest.fixture(params=[False, True]) -def use_delayed_gate_synthesis(request): - return request.param - - -def _get_transformers(use_delayed_gate_synthesis, error_budget): - if not use_delayed_gate_synthesis: - transformers = [ - transpile_to_native_gates, - synthesize_clifford_t(error_budget), - create_big_graph_from_subcircuits(fast_ruby_slippers), - ] - else: - transformers = [ - transpile_to_native_gates, - create_big_graph_from_subcircuits(fast_ruby_slippers), - ] - return transformers - - -def search_extra(this_dict, field): - return this_dict.get(field, this_dict["extra"].get(field)) - - -@pytest.mark.parametrize( - "quantum_program,steps_to_extrapolate_from,n_measurement_steps_fit_type", - [ - ( - QuantumProgram( - [ - Circuit([H(0), RZ(np.pi / 14)(0), CNOT(0, 1)]), - Circuit([H(0), H(1), RZ(np.pi / 14)(0)]), - ], - 10, - lambda x: [0] + [1] * x + [0], - ), - [2, 3, 4, 5], - "logarithmic", - ), - ( - QuantumProgram( - [ - Circuit([H(0), RZ(np.pi / 14)(0), CNOT(0, 1)]), - Circuit([H(0), H(1), RZ(np.pi / 14)(0)]), - ], - 10, - lambda x: [0] + [1] * x + [0], - ), - [2, 3, 4, 5], - "linear", - ), - ( - QuantumProgram( - [ - Circuit([H(0), RZ(np.pi / 14)(0), CNOT(0, 1)]), - Circuit([H(0), H(1), RZ(np.pi / 14)(0)]), - Circuit([H(0), H(1), CNOT(0, 1)]), - ], - 20, - lambda x: [0] + [1, 2] * x + [0], - ), - [2, 3, 4, 5, 10], - "linear", - ), - ], -) -def test_get_resource_estimations_for_small_program_gives_correct_results( - quantum_program, - steps_to_extrapolate_from, - use_delayed_gate_synthesis, - n_measurement_steps_fit_type, - optimization, -): - architecture_model = BASIC_SC_ARCHITECTURE_MODEL - - # set circuit generation weight to 0 - error_budget = ErrorBudget.from_weights(1e-2, 0, 1, 1) - algorithm_implementation = AlgorithmImplementation(quantum_program, error_budget, 1) - transformers = _get_transformers(use_delayed_gate_synthesis, error_budget) - - extrapolated_resource_estimates = get_custom_extrapolated_estimate( - algorithm_implementation, - estimator=ExtrapolationResourceEstimator( - architecture_model, - steps_to_extrapolate_from, - optimization=optimization, - substrate_scheduler_preset="optimized", - n_measurement_steps_fit_type=n_measurement_steps_fit_type, - ), - transformers=transformers, - ) - gsc_resource_estimates = get_custom_resource_estimation( - algorithm_implementation, - estimator=GraphResourceEstimator( - architecture_model, - optimization=optimization, - substrate_scheduler_preset="optimized", - ), - transformers=transformers, - ) - - test_dict = asdict(extrapolated_resource_estimates) - target_dict = asdict(gsc_resource_estimates) - - _fields_to_compare = [ - "n_nodes", - "max_graph_degree", - "code_distance", - "n_measurement_steps", - ] - for field in _fields_to_compare: - # esure that result isn't much lower than the target - assert search_extra(test_dict, field) >= search_extra(target_dict, field) * 0.47 - # allow for larger margin of error when overestimating - assert 3 * search_extra(target_dict, field) >= search_extra(test_dict, field) - - -@pytest.mark.parametrize( - "quantum_program,steps_to_extrapolate_from,n_measurement_steps_fit_type", - [ - ( - QuantumProgram( - [ - Circuit([H(0), RZ(np.pi / 14)(0), CNOT(0, 1)]), - Circuit([H(0), H(1), RZ(np.pi / 14)(0)]), - ], - 1000, - lambda x: [0] + [1] * x + [0], - ), - [10, 20, 50], - "logarithmic", - ), - ( - QuantumProgram( - [ - Circuit([H(0), RZ(np.pi / 14)(0), CNOT(0, 1)]), - Circuit([H(0), H(1), RZ(np.pi / 14)(0)]), - Circuit([H(0), H(1), CNOT(0, 1)]), - ], - 100, - lambda x: [0] + [1, 2] * x + [0], - ), - [2, 3, 5, 7, 10, 15, 25], - "linear", - ), - ], -) -def test_get_resource_estimations_for_large_program_gives_correct_results( - quantum_program, - steps_to_extrapolate_from, - use_delayed_gate_synthesis, - n_measurement_steps_fit_type, - optimization, -): - architecture_model = BASIC_SC_ARCHITECTURE_MODEL - # set circuit generation weight to 0 - error_budget = ErrorBudget.from_weights(1e-2, 0, 1, 1) - algorithm_implementation = AlgorithmImplementation(quantum_program, error_budget, 1) - transformers = _get_transformers(use_delayed_gate_synthesis, error_budget) - - extrapolated_resource_estimates = get_custom_extrapolated_estimate( - algorithm_implementation, - estimator=ExtrapolationResourceEstimator( - architecture_model, - steps_to_extrapolate_from, - n_measurement_steps_fit_type=n_measurement_steps_fit_type, - optimization=optimization, - max_graph_degree_fit_type="linear", - ), - transformers=transformers, - ) - gsc_resource_estimates = get_custom_resource_estimation( - algorithm_implementation, - estimator=GraphResourceEstimator(architecture_model, optimization=optimization), - transformers=transformers, - ) - - test_dict = asdict(extrapolated_resource_estimates) - target_dict = asdict(gsc_resource_estimates) - - _fields_to_compare_harshly = ["n_nodes", "n_logical_qubits", "n_measurement_steps"] - for field in _fields_to_compare_harshly: - # esure that result isn't much lower than the target - assert search_extra(test_dict, field) >= search_extra(target_dict, field) * 0.5 - # allow for larger margin of error when overestimating - assert 10 * search_extra(target_dict, field) >= search_extra(test_dict, field) - - assert ( - abs( - extrapolated_resource_estimates.code_distance - - gsc_resource_estimates.code_distance - ) - <= 3 - ) - - -def test_better_architecture_does_not_require_more_resources( - use_delayed_gate_synthesis, optimization -): - low_noise_architecture_model = replace( - BASIC_SC_ARCHITECTURE_MODEL, physical_qubit_error_rate=1e-4 - ) - - high_noise_architecture_model = BASIC_SC_ARCHITECTURE_MODEL - - # set circuit generation weight to 0 - error_budget = ErrorBudget.from_weights(1e-3, 0, 1, 1) - transformers = _get_transformers(use_delayed_gate_synthesis, error_budget) - - circuit = Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)]) - quantum_program = QuantumProgram( - subroutines=[circuit], - steps=100, - calculate_subroutine_sequence=lambda x: [0] * x, - ) - algorithm_implementation = AlgorithmImplementation(quantum_program, error_budget, 1) - low_noise_resource_estimates = get_custom_extrapolated_estimate( - algorithm_implementation, - estimator=ExtrapolationResourceEstimator( - low_noise_architecture_model, [1, 2, 3, 4], optimization=optimization - ), - transformers=transformers, - ) - - high_noise_resource_estimates = get_custom_extrapolated_estimate( - algorithm_implementation, - estimator=ExtrapolationResourceEstimator( - high_noise_architecture_model, [1, 2, 3, 4], optimization=optimization - ), - transformers=transformers, - ) - - assert ( - low_noise_resource_estimates.n_physical_qubits - <= high_noise_resource_estimates.n_physical_qubits - ) - assert ( - low_noise_resource_estimates.code_distance - <= high_noise_resource_estimates.code_distance - ) - assert ( - low_noise_resource_estimates.total_time_in_seconds - <= high_noise_resource_estimates.total_time_in_seconds - ) - - -def test_higher_error_budget_does_not_require_more_resources( - use_delayed_gate_synthesis, optimization -): - architecture_model = BASIC_SC_ARCHITECTURE_MODEL - low_failure_tolerance = 1e-3 - high_failure_tolerance = 1e-2 - - # set circuit generation weight to 0 - low_error_budget = ErrorBudget.from_weights(low_failure_tolerance, 0, 1, 1) - high_error_budget = ErrorBudget.from_weights(high_failure_tolerance, 0, 1, 1) - - low_error_transformers = _get_transformers( - use_delayed_gate_synthesis, low_error_budget - ) - high_error_transformers = _get_transformers( - use_delayed_gate_synthesis, high_error_budget - ) - - circuit = Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)]) - quantum_program = QuantumProgram( - subroutines=[circuit], - steps=100, - calculate_subroutine_sequence=lambda x: [0] * x, - ) - algorithm_implementation_low_error_budget = AlgorithmImplementation( - quantum_program, low_error_budget, 1 - ) - algorithm_implementation_high_error_budget = AlgorithmImplementation( - quantum_program, high_error_budget, 1 - ) - - low_error_resource_estimates = get_custom_extrapolated_estimate( - algorithm_implementation_low_error_budget, - estimator=ExtrapolationResourceEstimator( - architecture_model, [1, 2, 3, 4], optimization=optimization - ), - transformers=low_error_transformers, - ) - - high_error_resource_estimates = get_custom_extrapolated_estimate( - algorithm_implementation_high_error_budget, - estimator=ExtrapolationResourceEstimator( - architecture_model, [1, 2, 3, 4], optimization=optimization - ), - transformers=high_error_transformers, - ) - - assert ( - high_error_resource_estimates.n_physical_qubits - <= low_error_resource_estimates.n_physical_qubits - ) - assert ( - high_error_resource_estimates.code_distance - <= low_error_resource_estimates.code_distance - ) - assert ( - high_error_resource_estimates.total_time_in_seconds - <= low_error_resource_estimates.total_time_in_seconds - ) diff --git a/tests/benchq/resource_estimation/graph_estimators/decoder_test_data.csv b/tests/benchq/resource_estimators/decoder_test_data.csv similarity index 100% rename from tests/benchq/resource_estimation/graph_estimators/decoder_test_data.csv rename to tests/benchq/resource_estimators/decoder_test_data.csv diff --git a/tests/benchq/resource_estimation/test_azure_estimator.py b/tests/benchq/resource_estimators/test_azure_estimator.py similarity index 77% rename from tests/benchq/resource_estimation/test_azure_estimator.py rename to tests/benchq/resource_estimators/test_azure_estimator.py index 12314629..9701b2ce 100644 --- a/tests/benchq/resource_estimation/test_azure_estimator.py +++ b/tests/benchq/resource_estimators/test_azure_estimator.py @@ -5,9 +5,9 @@ from orquestra.quantum.circuits import CNOT, RZ, Circuit, H from benchq.algorithms.data_structures import AlgorithmImplementation, ErrorBudget -from benchq.problem_embeddings.quantum_program import get_program_from_circuit +from benchq.problem_embeddings.quantum_program import QuantumProgram from benchq.quantum_hardware_modeling.hardware_architecture_models import IONTrapModel -from benchq.resource_estimators.azure_estimator import AzureResourceEstimator +from benchq.resource_estimators.azure_estimator import azure_estimator SKIP_AZURE = pytest.mark.skipif( os.getenv("BENCHQ_TEST_AZURE") is None, @@ -32,7 +32,7 @@ def test_better_architecture_does_not_require_more_resources() -> None: # set circuit generation weight to 0 error_budget = ErrorBudget.from_weights(1e-3, 0, 1, 1) - quantum_program = get_program_from_circuit( + quantum_program = QuantumProgram.from_circuit( Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)]) ) @@ -40,15 +40,13 @@ def test_better_architecture_does_not_require_more_resources() -> None: program=quantum_program, error_budget=error_budget, n_shots=1 ) - low_quality_azure_re = AzureResourceEstimator( - hw_model=low_quality_architecture_model + low_quality_resource_estimates = azure_estimator( + alg_impl, low_quality_architecture_model ) - high_quality_azure_re = AzureResourceEstimator( - hw_model=high_quality_architecture_model - ) - low_quality_resource_estimates = low_quality_azure_re.estimate(alg_impl) - high_quality_resource_estimates = high_quality_azure_re.estimate(alg_impl) + high_quality_resource_estimates = azure_estimator( + alg_impl, high_quality_architecture_model + ) assert ( low_quality_resource_estimates.n_physical_qubits @@ -69,7 +67,7 @@ def test_higher_error_budget_requires_less_resources() -> None: low_failure_tolerance = 1e-5 high_failure_tolerance = 1e-3 - quantum_program = get_program_from_circuit( + quantum_program = QuantumProgram.from_circuit( Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)]) ) @@ -85,10 +83,9 @@ def test_higher_error_budget_requires_less_resources() -> None: error_budget=ErrorBudget.from_weights(high_failure_tolerance, 0, 1, 1), n_shots=1, ) - azure_re = AzureResourceEstimator() - low_budget_resource_estimates = azure_re.estimate(low_error_budget_impl) - high_budget_resource_estimates = azure_re.estimate(high_error_budget_impl) + low_budget_resource_estimates = azure_estimator(low_error_budget_impl) + high_budget_resource_estimates = azure_estimator(high_error_budget_impl) assert ( low_budget_resource_estimates.n_physical_qubits diff --git a/tests/benchq/resource_estimation/graph_estimators/test_graph_estimator.py b/tests/benchq/resource_estimators/test_graph_estimator.py similarity index 51% rename from tests/benchq/resource_estimation/graph_estimators/test_graph_estimator.py rename to tests/benchq/resource_estimators/test_graph_estimator.py index 37f1766a..18769e25 100644 --- a/tests/benchq/resource_estimation/graph_estimators/test_graph_estimator.py +++ b/tests/benchq/resource_estimators/test_graph_estimator.py @@ -6,58 +6,39 @@ from orquestra.quantum.circuits import CNOT, RX, RY, RZ, Circuit, H, T from benchq.algorithms.data_structures import AlgorithmImplementation, ErrorBudget -from benchq.compilation import get_ruby_slippers_compiler -from benchq.decoder_modeling import DecoderModel -from benchq.magic_state_distillation.litinski_factories import ( - _ERROR_RATE_FACTORY_MAPPING, -) -from benchq.problem_embeddings.quantum_program import ( - QuantumProgram, - get_program_from_circuit, +from benchq.compilation.graph_states import ( + get_implementation_compiler, + get_ruby_slippers_circuit_compiler, ) +from benchq.decoder_modeling import DecoderModel +from benchq.problem_embeddings.quantum_program import QuantumProgram from benchq.quantum_hardware_modeling import ( BASIC_ION_TRAP_ARCHITECTURE_MODEL, BASIC_SC_ARCHITECTURE_MODEL, DETAILED_ION_TRAP_ARCHITECTURE_MODEL, ) -from benchq.resource_estimators.graph_estimators import ( - GraphResourceEstimator, - create_big_graph_from_subcircuits, - get_custom_resource_estimation, - synthesize_clifford_t, - transpile_to_native_gates, -) - -fast_ruby_slippers = get_ruby_slippers_compiler( - max_graph_size=10, - decomposition_strategy=0, +from benchq.resource_estimators.graph_estimator import GraphResourceEstimator + +fast_ruby_slippers = get_implementation_compiler( + circuit_compiler=get_ruby_slippers_circuit_compiler( + takes_graph_input=False, + gives_graph_output=False, + max_graph_size=10, + decomposition_strategy=0, + ) ) -@pytest.fixture(params=["time", "space"]) +@pytest.fixture(params=["Time", "Space"]) def optimization(request): return request.param @pytest.fixture(params=[True, False]) -def use_delayed_gate_synthesis(request): +def transpile_to_clifford_t(request): return request.param -def _get_transformers(use_delayed_gate_synthesis, error_budget): - if use_delayed_gate_synthesis: - transformers = [ - synthesize_clifford_t(error_budget), - create_big_graph_from_subcircuits(fast_ruby_slippers), - ] - else: - transformers = [ - transpile_to_native_gates, - create_big_graph_from_subcircuits(fast_ruby_slippers), - ] - return transformers - - @pytest.mark.parametrize( "architecture_model, supports_hardware_resources", [ @@ -67,7 +48,10 @@ def _get_transformers(use_delayed_gate_synthesis, error_budget): ], ) def test_resource_estimations_returns_results_for_different_architectures( - architecture_model, supports_hardware_resources + optimization, + architecture_model, + supports_hardware_resources, + transpile_to_clifford_t, ): # set circuit generation weight to 0 error_budget = ErrorBudget.from_weights(1e-3, 0, 1, 1) @@ -75,12 +59,14 @@ def test_resource_estimations_returns_results_for_different_architectures( [Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)])], 1, lambda x: [0] ) algorithm_implementation = AlgorithmImplementation(quantum_program, error_budget, 1) + if transpile_to_clifford_t: + algorithm_implementation = algorithm_implementation.transpile_to_clifford_t() - transformers = _get_transformers(use_delayed_gate_synthesis, error_budget) - gsc_resource_estimates = get_custom_resource_estimation( + estimator = GraphResourceEstimator(optimization) + gsc_resource_estimates = estimator.compile_and_estimate( algorithm_implementation, - estimator=GraphResourceEstimator(architecture_model), - transformers=transformers, + fast_ruby_slippers, + architecture_model, ) assert gsc_resource_estimates @@ -91,108 +77,131 @@ def test_resource_estimations_returns_results_for_different_architectures( @pytest.mark.parametrize( - "quantum_program,expected_results", + "quantum_program,optimization,expected_results", [ ( QuantumProgram( [Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)])], 1, lambda x: [0] ), - {"n_measurement_steps": 3, "n_nodes": 3, "n_logical_qubits": 4}, + "Space", + {"code_distance": 9, "n_logical_qubits": 2}, + ), + ( + QuantumProgram.from_circuit( + Circuit([RX(np.pi / 4)(0), RY(np.pi / 4)(0), CNOT(0, 1)]) + ), + "Space", + {"code_distance": 9, "n_logical_qubits": 2}, + ), + ( + QuantumProgram.from_circuit( + Circuit([H(0)] + [CNOT(i, i + 1) for i in range(3)]) + ), + "Space", + {"code_distance": 9, "n_logical_qubits": 2}, + ), + ( + QuantumProgram.from_circuit( + Circuit([H(0)] + [CNOT(i, i + 1) for i in range(3)] + [T(1), T(2)]) + ), + "Space", + {"code_distance": 9, "n_logical_qubits": 2}, + ), + ( + QuantumProgram.from_circuit( + Circuit([H(0), T(0), CNOT(0, 1), T(2), CNOT(2, 3)]) + ), + "Space", + {"code_distance": 9, "n_logical_qubits": 2}, + ), + ( + QuantumProgram( + [Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)])], 1, lambda x: [0] + ), + "Time", + {"code_distance": 9, "n_logical_qubits": 12}, ), ( - get_program_from_circuit( + QuantumProgram.from_circuit( Circuit([RX(np.pi / 4)(0), RY(np.pi / 4)(0), CNOT(0, 1)]) ), - {"n_measurement_steps": 4, "n_nodes": 4, "n_logical_qubits": 4}, + "Time", + {"code_distance": 11, "n_logical_qubits": 12}, ), ( - get_program_from_circuit( + QuantumProgram.from_circuit( Circuit([H(0)] + [CNOT(i, i + 1) for i in range(3)]) ), - {"n_measurement_steps": 4, "n_nodes": 4, "n_logical_qubits": 6}, + "Time", + {"code_distance": 9, "n_logical_qubits": 16}, ), ( - get_program_from_circuit( + QuantumProgram.from_circuit( Circuit([H(0)] + [CNOT(i, i + 1) for i in range(3)] + [T(1), T(2)]) ), - {"n_measurement_steps": 6, "n_nodes": 6, "n_logical_qubits": 10}, + "Time", + {"code_distance": 9, "n_logical_qubits": 24}, ), ( - get_program_from_circuit( + QuantumProgram.from_circuit( Circuit([H(0), T(0), CNOT(0, 1), T(2), CNOT(2, 3)]) ), - {"n_measurement_steps": 3, "n_nodes": 3, "n_logical_qubits": 4}, + "Time", + {"code_distance": 9, "n_logical_qubits": 24}, ), ], ) def test_get_resource_estimations_for_program_gives_correct_results( - quantum_program, expected_results, optimization, use_delayed_gate_synthesis + quantum_program, expected_results, transpile_to_clifford_t, optimization ): architecture_model = BASIC_SC_ARCHITECTURE_MODEL # set circuit generation weight to 0 error_budget = ErrorBudget.from_weights(1e-3, 0, 1, 1) algorithm_implementation = AlgorithmImplementation(quantum_program, error_budget, 1) + if transpile_to_clifford_t: + algorithm_implementation = algorithm_implementation.transpile_to_clifford_t() + estimator = GraphResourceEstimator(optimization) - transformers = _get_transformers(use_delayed_gate_synthesis, error_budget) - gsc_resource_estimates = get_custom_resource_estimation( + resource_estimates = estimator.compile_and_estimate( algorithm_implementation, - estimator=GraphResourceEstimator(architecture_model), - transformers=transformers, + fast_ruby_slippers, + architecture_model, ) - # Extract only keys that we want to compare - test_results = { - "n_measurement_steps": gsc_resource_estimates.extra.n_measurement_steps, - "n_nodes": gsc_resource_estimates.extra.n_nodes, - "n_logical_qubits": gsc_resource_estimates.n_logical_qubits, - } - for field in test_results.keys(): - assert test_results[field] == expected_results[field] - - # Note that error_budget is a bound for the sum of the gate synthesis error and - # logical error. Therefore the expression below is a loose upper bound for the - # logical error rate. - assert ( - gsc_resource_estimates.logical_error_rate < error_budget.total_failure_tolerance - ) + assert resource_estimates.code_distance == expected_results["code_distance"] + assert resource_estimates.n_logical_qubits == expected_results["n_logical_qubits"] def test_better_architecture_does_not_require_more_resources( optimization, - use_delayed_gate_synthesis, + transpile_to_clifford_t, ): - low_noise_architecture_model = BASIC_SC_ARCHITECTURE_MODEL + low_noise_architecture_model = BASIC_ION_TRAP_ARCHITECTURE_MODEL high_noise_architecture_model = replace( - BASIC_SC_ARCHITECTURE_MODEL, physical_qubit_error_rate=1e-2 + BASIC_ION_TRAP_ARCHITECTURE_MODEL, physical_qubit_error_rate=1e-3 ) # set algorithm failure tolerance to 0 error_budget = ErrorBudget.from_weights(1e-2, 0, 1, 1) - transformers = _get_transformers(use_delayed_gate_synthesis, error_budget) - - quantum_program = get_program_from_circuit( + quantum_program = QuantumProgram.from_circuit( Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)]) ) algorithm_implementation = AlgorithmImplementation(quantum_program, error_budget, 1) - low_noise_resource_estimates = get_custom_resource_estimation( + estimator = GraphResourceEstimator(optimization) + + low_noise_resource_estimates = estimator.compile_and_estimate( algorithm_implementation, - estimator=GraphResourceEstimator( - low_noise_architecture_model, optimization=optimization - ), - transformers=transformers, + fast_ruby_slippers, + low_noise_architecture_model, ) - high_noise_resource_estimates = get_custom_resource_estimation( + high_noise_resource_estimates = estimator.compile_and_estimate( algorithm_implementation, - estimator=GraphResourceEstimator( - high_noise_architecture_model, - optimization=optimization, - magic_state_factory_iterator=_ERROR_RATE_FACTORY_MAPPING[1e-4], - ), - transformers=transformers, + fast_ruby_slippers, + high_noise_architecture_model, ) assert ( @@ -211,7 +220,7 @@ def test_better_architecture_does_not_require_more_resources( def test_higher_error_budget_does_not_require_more_resources( optimization, - use_delayed_gate_synthesis, + transpile_to_clifford_t, ): architecture_model = BASIC_SC_ARCHITECTURE_MODEL low_failure_tolerance = 1e-3 @@ -221,14 +230,7 @@ def test_higher_error_budget_does_not_require_more_resources( low_error_budget = ErrorBudget.from_weights(low_failure_tolerance, 0, 1, 1) high_error_budget = ErrorBudget.from_weights(high_failure_tolerance, 0, 1, 1) - low_error_transformers = _get_transformers( - use_delayed_gate_synthesis, low_error_budget - ) - high_error_transformers = _get_transformers( - use_delayed_gate_synthesis, high_error_budget - ) - - quantum_program = get_program_from_circuit( + quantum_program = QuantumProgram.from_circuit( Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)]) ) algorithm_implementation_low_error_budget = AlgorithmImplementation( @@ -237,17 +239,26 @@ def test_higher_error_budget_does_not_require_more_resources( algorithm_implementation_high_error_budget = AlgorithmImplementation( quantum_program, high_error_budget, 1 ) + if transpile_to_clifford_t: + algorithm_implementation_low_error_budget = ( + algorithm_implementation_low_error_budget.transpile_to_clifford_t() + ) + algorithm_implementation_high_error_budget = ( + algorithm_implementation_high_error_budget.transpile_to_clifford_t() + ) - low_error_resource_estimates = get_custom_resource_estimation( + estimator = GraphResourceEstimator(optimization) + + low_error_resource_estimates = estimator.compile_and_estimate( algorithm_implementation_low_error_budget, - estimator=GraphResourceEstimator(architecture_model, optimization=optimization), - transformers=low_error_transformers, + fast_ruby_slippers, + architecture_model, ) - high_error_resource_estimates = get_custom_resource_estimation( + high_error_resource_estimates = estimator.compile_and_estimate( algorithm_implementation_high_error_budget, - estimator=GraphResourceEstimator(architecture_model, optimization=optimization), - transformers=high_error_transformers, + fast_ruby_slippers, + architecture_model, ) assert ( @@ -268,16 +279,16 @@ def test_get_resource_estimations_for_program_accounts_for_decoder(optimization) architecture_model = BASIC_SC_ARCHITECTURE_MODEL # set circuit generation weight to 0 error_budget = ErrorBudget.from_weights(1e-3, 0, 1, 1) - quantum_program = get_program_from_circuit( + quantum_program = QuantumProgram.from_circuit( Circuit([H(0), RZ(np.pi / 4)(0), CNOT(0, 1)]) ) algorithm_implementation = AlgorithmImplementation(quantum_program, error_budget, 1) + estimator = GraphResourceEstimator(optimization) - transformers = _get_transformers(True, error_budget) - gsc_resource_estimates_no_decoder = get_custom_resource_estimation( + gsc_resource_estimates_no_decoder = estimator.compile_and_estimate( algorithm_implementation, - estimator=GraphResourceEstimator(architecture_model, decoder_model=None), - transformers=transformers, + fast_ruby_slippers, + architecture_model, ) file_path = os.path.join( @@ -285,12 +296,12 @@ def test_get_resource_estimations_for_program_accounts_for_decoder(optimization) ) decoder = DecoderModel.from_csv(file_path) - gsc_resource_estimates_with_decoder = get_custom_resource_estimation( + gsc_resource_estimates_with_decoder = estimator.compile_and_estimate( algorithm_implementation, - estimator=GraphResourceEstimator(architecture_model, decoder_model=decoder), - transformers=transformers, + fast_ruby_slippers, + architecture_model, + decoder_model=decoder, ) assert gsc_resource_estimates_no_decoder.decoder_info is None assert gsc_resource_estimates_with_decoder.decoder_info is not None - assert gsc_resource_estimates_with_decoder.decoder_info is not None diff --git a/tests/benchq/resource_estimation/footprint_estimators/test_openfermion_estimator.py b/tests/benchq/resource_estimators/test_openfermion_estimator.py similarity index 98% rename from tests/benchq/resource_estimation/footprint_estimators/test_openfermion_estimator.py rename to tests/benchq/resource_estimators/test_openfermion_estimator.py index 8f130d31..19dbfbfd 100644 --- a/tests/benchq/resource_estimation/footprint_estimators/test_openfermion_estimator.py +++ b/tests/benchq/resource_estimators/test_openfermion_estimator.py @@ -1,9 +1,7 @@ import numpy import pytest -from benchq.resource_estimators.footprint_estimators.openfermion_estimator import ( - _cost_estimator, -) +from benchq.resource_estimators.openfermion_estimator import _cost_estimator @pytest.mark.parametrize( diff --git a/tests/benchq/visualization_tools/test_resource_allocation.py b/tests/benchq/visualization_tools/test_resource_allocation.py new file mode 100644 index 00000000..cc1bd61e --- /dev/null +++ b/tests/benchq/visualization_tools/test_resource_allocation.py @@ -0,0 +1,151 @@ +import pandas as pd +import pytest + +from benchq.visualization_tools.resource_allocation import ResourceAllocation + + +@pytest.fixture +def time_allocation(): + return ResourceAllocation("cycles") + + +@pytest.fixture +def possible_processes(): + return ["Tstate-to-Tgate", "distillation", "entanglement"] + + +@pytest.mark.parametrize( + "processes_list, time_per_process", + [ + ( + [ + ["Tstate-to-Tgate"], + ["Tstate-to-Tgate"], + ], + [10, 20], + ), + ( + [ + ["Tstate-to-Tgate", "distillation"], + ["Tstate-to-Tgate", "distillation"], + ], + [30, 40], + ), + ], +) +def test_logg_adds_correctly(time_allocation, processes_list, time_per_process): + for processes, cycles in zip(processes_list, time_per_process): + time_allocation.log(cycles, *processes) + + assert time_allocation.exclusive(*processes_list[0]) == sum(time_per_process) + assert time_allocation.inclusive(*processes_list[0]) == sum(time_per_process) + + +@pytest.mark.parametrize( + "processes_list, time_per_process", + [ + ( + [ + "Tstate-to-Tgate", + "distillation", + ], + [10, 20], + ), + ( + [ + "Tstate-to-Tgate", + "distillation", + "entanglement", + ], + [10, 20, 30], + ), + ], +) +def test_parallel_logging(time_allocation, processes_list, time_per_process): + time_allocation.log_parallelized(time_per_process, processes_list) + + for process_num in range(len(processes_list)): + assert time_allocation.exclusive(*processes_list[process_num:]) == 10 + + +def test_parallel_and_single_logging_non_constructive(time_allocation): + time_allocation.log(10, "Tstate-to-Tgate") + time_allocation.log_parallelized([30, 50], ["Tstate-to-Tgate", "distillation"]) + + assert time_allocation.exclusive("Tstate-to-Tgate") == 10 + assert time_allocation.exclusive("distillation") == 20 + assert time_allocation.exclusive("Tstate-to-Tgate", "distillation") == 30 + + assert time_allocation.inclusive("Tstate-to-Tgate") == 40 + assert time_allocation.inclusive("distillation") == 50 + + +def test_parallel_and_single_logging_constructive(time_allocation): + time_allocation.log(10, "Tstate-to-Tgate") + time_allocation.log_parallelized([30, 40], ["distillation", "Tstate-to-Tgate"]) + + assert time_allocation.exclusive("Tstate-to-Tgate") == 20 + assert time_allocation.exclusive("Tstate-to-Tgate", "distillation") == 30 + + assert time_allocation.inclusive("Tstate-to-Tgate") == 50 + assert time_allocation.inclusive("distillation") == 30 + + +@pytest.mark.parametrize( + "processes_list, time_per_process", + [ + ( + [ + ["Tstate-to-Tgate"], + ], + [10], + ), + ( + [ + ["Tstate-to-Tgate"], + ["distillation"], + ], + [10], + ), + ( + [ + ["Tstate-to-Tgate", "distillation"], + ], + [10], + ), + ( + [ + ["Tstate-to-Tgate"], + ["distillation"], + ["entanglement"], + ["Tstate-to-Tgate", "distillation"], + ], + [10, 20, 30, 40], + ), + ], +) +def test_conversion_to_dataframe( + time_allocation, possible_processes, processes_list, time_per_process +): + # add some cycles to the given processes + for processes, cycles in zip(processes_list, time_per_process): + time_allocation.log(cycles, *processes) + df = time_allocation.to_pandas_dataframe() + + # create a target DataFrame + dataframe_rows = [] + for processes, cycles in zip(processes_list, time_per_process): + dataframe_rows.append( + {process: process in processes for process in possible_processes} + ) + dataframe_rows[-1][time_allocation.resource_name] = cycles + target_df = pd.DataFrame(dataframe_rows) + + # Sort both DataFrames by all columns and then check if they are equal + df = df[sorted(df.columns)] + df = df.sort_values(by=list(df.columns)).reset_index(drop=True) + + target_df = target_df[sorted(target_df.columns)] + target_df = target_df.sort_values(by=list(target_df.columns)).reset_index(drop=True) + + assert df.equals(target_df)