From 66455144a5b99debd0df2818e77e6199d1dcfa8f Mon Sep 17 00:00:00 2001 From: Noureldin Date: Wed, 23 Aug 2023 15:16:50 +0100 Subject: [PATCH 1/3] Create data classes used by the Azure physical costing model --- qualtran/surface_code/__init__.py | 5 ++ qualtran/surface_code/algorithm_specs.py | 40 +++++++++ qualtran/surface_code/physical_parameters.py | 48 ++++++++++ .../quantum_error_correction_scheme.py | 90 +++++++++++++++++++ .../quantum_error_correction_scheme_test.py | 77 ++++++++++++++++ qualtran/surface_code/rotation_cost_model.py | 82 +++++++++++++++++ .../surface_code/rotation_cost_model_test.py | 21 +++++ qualtran/surface_code/t_factory.py | 47 ++++++++++ qualtran/surface_code/t_factory_test.py | 24 +++++ 9 files changed, 434 insertions(+) create mode 100644 qualtran/surface_code/algorithm_specs.py create mode 100644 qualtran/surface_code/physical_parameters.py create mode 100644 qualtran/surface_code/quantum_error_correction_scheme.py create mode 100644 qualtran/surface_code/quantum_error_correction_scheme_test.py create mode 100644 qualtran/surface_code/rotation_cost_model.py create mode 100644 qualtran/surface_code/rotation_cost_model_test.py create mode 100644 qualtran/surface_code/t_factory.py create mode 100644 qualtran/surface_code/t_factory_test.py diff --git a/qualtran/surface_code/__init__.py b/qualtran/surface_code/__init__.py index ce76a8d10..ae406c1a3 100644 --- a/qualtran/surface_code/__init__.py +++ b/qualtran/surface_code/__init__.py @@ -11,3 +11,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +from qualtran.surface_code.algorithm_specs import AlgorithmSpecs +from qualtran.surface_code.physical_parameters import PhysicalParameters +from qualtran.surface_code.rotation_cost_model import RotationCostLinearModel, RotationCostModel +from qualtran.surface_code.t_factory import TFactory diff --git a/qualtran/surface_code/algorithm_specs.py b/qualtran/surface_code/algorithm_specs.py new file mode 100644 index 000000000..a755d7aa1 --- /dev/null +++ b/qualtran/surface_code/algorithm_specs.py @@ -0,0 +1,40 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import attr +from attrs import frozen + +_PRETTY_FLOAT = attr.ib(type=float, default=0.0, repr=lambda x: f'{x:g}') + + +@frozen +class AlgorithmSpecs: + """AlgorithmSpecs is a summary of a quantum algorithm/circuit. + + Attributes: + algorithm_qubits: Number of qubits used by the algorithm. + measurements: Number of Measurements. + t_gates: Number of T gates. + toffoli_gates: Number of Toffoli gates. + rotation_gates: Number of Rotations. + rotation_circuit_depth: Depth of rotation circuit. + """ + + algorithm_qubits = _PRETTY_FLOAT # Number of algorithm qubits $Q_{alg}$ + measurements = _PRETTY_FLOAT # Number of measurements $M_R$. + t_gates = _PRETTY_FLOAT # Number of T gates $M_T$. + toffoli_gates = _PRETTY_FLOAT # Number of Toffoli gates $M_{Tof}$. + rotation_gates = _PRETTY_FLOAT # Number of Rotations $M_R$. + rotation_circuit_depth = _PRETTY_FLOAT # Depth of rotation circuit $D_R$. diff --git a/qualtran/surface_code/physical_parameters.py b/qualtran/surface_code/physical_parameters.py new file mode 100644 index 000000000..33d7cb6ee --- /dev/null +++ b/qualtran/surface_code/physical_parameters.py @@ -0,0 +1,48 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import attr +from attrs import frozen + + +@frozen +class PhysicalParameters: + """PhysicalParameters contains physical properties of a quantum computer. + + Attributes: + t_gate: Clifford gate time. + t_meas: Measurement time. + physical_error_rate: Physical error rate. + reference: Source of these estimates. + """ + + t_gate = attr.ib(type=float, default=1e-6, repr=lambda x: f'{x:g}') # 1us + t_meas = attr.ib(type=float, default=1e-6, repr=lambda x: f'{x:g}') # 1us + + physical_error_rate = attr.ib(type=float, default=1e-3, repr=lambda x: f'{x:g}') + + reference = attr.ib(type=str, default='') + + +FowlerGidney = PhysicalParameters( + t_gate=1e-6, t_meas=1e-6, physical_error_rate=1e-3, reference='https://arxiv.org/abs/1808.06709' +) + + +BeverlandEtAl = PhysicalParameters( + t_gate=50 * 1e-9, + t_meas=100 * 1e-9, + physical_error_rate=1e-4, + reference='https://arxiv.org/abs/2211.07629', +) diff --git a/qualtran/surface_code/quantum_error_correction_scheme.py b/qualtran/surface_code/quantum_error_correction_scheme.py new file mode 100644 index 000000000..ad6b0160a --- /dev/null +++ b/qualtran/surface_code/quantum_error_correction_scheme.py @@ -0,0 +1,90 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import attr +import numpy as np +from attrs import frozen + +from qualtran.surface_code.physical_parameters import PhysicalParameters + + +@frozen +class QuantumErrorCorrectionScheme: + """QuantumErrorCorrectionScheme represents a quantum error correction scheme. + + QuantumErrorCorrectionScheme provides estimates for the logical error rate, + number of physical qubits and the logical time step given a code distance and + physical assumptions. + + Attributes: + error_rate_scaler: Logical error rate coefficient. + error_rate_threshold: Logical error rate threshold. + reference: source of the estimates. + """ + + error_rate_scaler = attr.ib(type=float, default=0.1, repr=lambda x: f'{x:g}') + error_rate_threshold = attr.ib(type=float, default=0.01, repr=lambda x: f'{x:g}') + reference = attr.ib(type=str, default='') + + def logical_error_rate( + self, code_distance: int | np.ndarray, physical_error_rate: float | np.ndarray + ) -> float | np.ndarray: + """Computes the logical error rate.""" + return self.error_rate_scaler * np.power( + physical_error_rate / self.error_rate_threshold, (code_distance + 1) / 2 + ) + + def physical_qubits(self, code_distance: int | np.ndarray) -> int | np.ndarray: + """Computes number of physical qubits""" + + def logical_time_step( + self, code_distance: int | np.ndarray, physical_parameters: PhysicalParameters + ) -> float: + """Computes the logical time step.""" + + +class GateBasedSurfaceCode(QuantumErrorCorrectionScheme): + """Gate Based Surface Code.""" + + def physical_qubits(self, code_distance: int | np.ndarray) -> int | np.ndarray: + return 2 * code_distance**2 + + def logical_time_step( + self, code_distance: int | np.ndarray, physical_parameters: PhysicalParameters + ) -> float: + return (4 * physical_parameters.t_gate + 2 * physical_parameters.t_meas) * code_distance + + +class MeasurementBasedSurfaceCode(QuantumErrorCorrectionScheme): + """Measurement Based Surface Code.""" + + def physical_qubits(self, code_distance: int | np.ndarray) -> int | np.ndarray: + return 2 * code_distance**2 + + def logical_time_step( + self, code_distance: int | np.ndarray, physical_parameters: PhysicalParameters + ) -> float: + return 20 * physical_parameters.t_meas * code_distance + + +class MeasurementBasedHastingsHaahCode(QuantumErrorCorrectionScheme): + """Measurement Based Hastings&Haah Code.""" + + def physical_qubits(self, code_distance: int | np.ndarray) -> int | np.ndarray: + return 4 * code_distance**2 + 8 * (code_distance - 1) + + def logical_time_step( + self, code_distance: int | np.ndarray, physical_parameters: PhysicalParameters + ) -> float: + return 3 * physical_parameters.t_meas * code_distance diff --git a/qualtran/surface_code/quantum_error_correction_scheme_test.py b/qualtran/surface_code/quantum_error_correction_scheme_test.py new file mode 100644 index 000000000..0a5650003 --- /dev/null +++ b/qualtran/surface_code/quantum_error_correction_scheme_test.py @@ -0,0 +1,77 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +from qualtran.surface_code import quantum_error_correction_scheme as qecs +from qualtran.surface_code.physical_parameters import PhysicalParameters + + +@pytest.mark.parametrize( + 'qec,want', + [ + [qecs.GateBasedSurfaceCode(error_rate_scaler=0.03, error_rate_threshold=0.01), 3e-7], + [ + qecs.MeasurementBasedSurfaceCode(error_rate_scaler=0.04, error_rate_threshold=0.09), + 6.77e-12, + ], + [ + qecs.MeasurementBasedHastingsHaahCode( + error_rate_scaler=0.05, error_rate_threshold=0.06 + ), + 6.43e-11, + ], + ], +) +def test_logical_error_rate(qec: qecs.QuantumErrorCorrectionScheme, want: float): + assert qec.logical_error_rate(9, 1e-3) == pytest.approx(want) + + +@pytest.mark.parametrize( + 'qec,want', + [ + [qecs.GateBasedSurfaceCode(error_rate_scaler=0.03, error_rate_threshold=0.01), 242], + [qecs.MeasurementBasedSurfaceCode(error_rate_scaler=0.04, error_rate_threshold=0.09), 242], + [ + qecs.MeasurementBasedHastingsHaahCode( + error_rate_scaler=0.05, error_rate_threshold=0.06 + ), + 564, + ], + ], +) +def test_physical_qubits(qec: qecs.QuantumErrorCorrectionScheme, want: int): + assert qec.physical_qubits(11) == want + + +@pytest.mark.parametrize( + 'qec,want', + [ + [qecs.GateBasedSurfaceCode(error_rate_scaler=0.03, error_rate_threshold=0.01), 4.8e-6], + [ + qecs.MeasurementBasedSurfaceCode(error_rate_scaler=0.04, error_rate_threshold=0.09), + 2.4e-5, + ], + [ + qecs.MeasurementBasedHastingsHaahCode( + error_rate_scaler=0.05, error_rate_threshold=0.06 + ), + 3.6e-6, + ], + ], +) +def test_logical_time_step(qec: qecs.QuantumErrorCorrectionScheme, want: float): + assert qec.logical_time_step( + 12, physical_parameters=PhysicalParameters(50e-9, 100e-9, 1e-4) + ) == pytest.approx(want) diff --git a/qualtran/surface_code/rotation_cost_model.py b/qualtran/surface_code/rotation_cost_model.py new file mode 100644 index 000000000..f90ba4aeb --- /dev/null +++ b/qualtran/surface_code/rotation_cost_model.py @@ -0,0 +1,82 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import abc + +import attr +import numpy as np +from attrs import frozen + +_PRETTY_FLOAT = attr.ib(type=float, repr=lambda x: f'{x:g}') + + +class RotationCostModel(abc.ABC): + """Analytical estimate of number of T gates needed to approximate a rotation given an error budget.""" + + @abc.abstractmethod + def mean_cost(self, error_budge: float | np.ndarray) -> float: + """Returns the mean number of T gates needed to approx a rotation.""" + + @abc.abstractmethod + def max_cost(self, error_budge: float | np.ndarray) -> float: + """Returns the max number of T gates needed to approx a rotation.""" + + +@frozen +class RotationCostLinearModel(RotationCostModel): + r"""RotationCostLinearModel is a linear model in the log of the error budget. + + #T gates = $-A \log_2{budget} + B$ + + Attributes: + A_mean: Mean value of the coefficient of $log_2{budget}$. + B_mean: Mean value of the offset/overhead. + A_max: Max value of the coefficient of $log_2{budget}$. + B_max: Max value of the offset/overhead. + """ + A_mean = _PRETTY_FLOAT + B_mean = _PRETTY_FLOAT + A_max = _PRETTY_FLOAT + B_max = _PRETTY_FLOAT + + gateset = attr.ib(type=str, default='') + approximation_protocol = attr.ib(type=str, default='') + reference = attr.ib(type=str, default='') + + def mean_cost(self, error_budge: float | np.ndarray) -> float: + return self.A_mean * np.log2(1.0 / error_budge) + self.B_mean + + def max_cost(self, error_budge: float | np.ndarray) -> float: + return self.A_max * np.log2(1.0 / error_budge) + self.B_max + + +MixedFallBackCliffordT = RotationCostLinearModel( + A_mean=0.53, + B_mean=4.86, + A_max=0.57, + B_max=8.83, + gateset='Clifford+T', + approximation_protocol='Mixed fallback', + reference='https://arxiv.org/abs/2203.10064:Table1', +) + +BeverlandEtAl = RotationCostLinearModel( + A_mean=0.53, + B_mean=5.3, + A_max=0.53, + B_max=5.3, + gateset='Clifford+T', + approximation_protocol='Mixed fallback', + reference='https://arxiv.org/abs/2211.07629:D2', +) diff --git a/qualtran/surface_code/rotation_cost_model_test.py b/qualtran/surface_code/rotation_cost_model_test.py new file mode 100644 index 000000000..86a257985 --- /dev/null +++ b/qualtran/surface_code/rotation_cost_model_test.py @@ -0,0 +1,21 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from qualtran.surface_code.rotation_cost_model import RotationCostLinearModel + + +def test_linear_model(): + model = RotationCostLinearModel(1, 2, 3, 4) + assert model.mean_cost(0.5) == 3 + assert model.max_cost(0.5) == 7 diff --git a/qualtran/surface_code/t_factory.py b/qualtran/surface_code/t_factory.py new file mode 100644 index 000000000..c76e99c34 --- /dev/null +++ b/qualtran/surface_code/t_factory.py @@ -0,0 +1,47 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import attr +from attrs import frozen + +from qualtran.surface_code.magic_state_factory import MagicStateCount, MagicStateFactory + +_PRETTY_FLOAT = attr.ib(type=float, default=0.0, repr=lambda x: f'{x:g}') + + +@frozen +class TFactory(MagicStateFactory): + """TFactory represents a magic state factory for T states. + + Attributes: + num_qubits: Number of qubits used by the factory. + duration: Time taken by the factory to produce T states. + t_states_rate: Number of T states per production cycle. + reference: Source of these estimates. + """ + + num_qubits = attr.ib(type=int, default=0) + duration = _PRETTY_FLOAT + t_states_rate = _PRETTY_FLOAT + error_rate = attr.ib(type=float, default=1e-9, repr=lambda x: f'{x:g}') + reference = attr.ib(type=str, default='') + + def footprint(self) -> int: + return self.num_qubits + + def n_cycles(self, n_magic: MagicStateCount) -> int: + return n_magic.all_t_count() / self.t_states_rate * self.duration + + def distillation_error(self, n_magic: MagicStateCount, phys_err: float) -> float: + return n_magic.all_t_count() / self.t_states_rate * phys_err diff --git a/qualtran/surface_code/t_factory_test.py b/qualtran/surface_code/t_factory_test.py new file mode 100644 index 000000000..07f28832f --- /dev/null +++ b/qualtran/surface_code/t_factory_test.py @@ -0,0 +1,24 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from qualtran.surface_code.t_factory import MagicStateCount, TFactory + + +def test_footprint(): + factory = TFactory(num_qubits=5, duration=1, t_states_rate=0.1) + magic_count = MagicStateCount(t_count=1, ccz_count=1) + assert factory.footprint() == 5 + assert factory.n_cycles(magic_count) == 50 + assert factory.distillation_error(magic_count, 0.5) == 25 From 933b6620bf8806c4de82738f961f726d9e1fae14 Mon Sep 17 00:00:00 2001 From: Noureldin Date: Wed, 30 Aug 2023 14:51:43 +0100 Subject: [PATCH 2/3] Update qualtran/surface_code/algorithm_specs.py Co-authored-by: Matthew Harrigan --- qualtran/surface_code/algorithm_specs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qualtran/surface_code/algorithm_specs.py b/qualtran/surface_code/algorithm_specs.py index a755d7aa1..5ee8d1121 100644 --- a/qualtran/surface_code/algorithm_specs.py +++ b/qualtran/surface_code/algorithm_specs.py @@ -21,7 +21,7 @@ @frozen class AlgorithmSpecs: - """AlgorithmSpecs is a summary of a quantum algorithm/circuit. + """Properties of a quantum algorithm that impact its physical cost Attributes: algorithm_qubits: Number of qubits used by the algorithm. From 1c65f1426a7e18634a693117cb3a6468b4efa571 Mon Sep 17 00:00:00 2001 From: Nour Yosri Date: Thu, 5 Oct 2023 15:38:28 -0700 Subject: [PATCH 3/3] remove qualtran/surface_code/algorithm_specs.py --- qualtran/surface_code/algorithm_specs.py | 40 ------------------------ 1 file changed, 40 deletions(-) delete mode 100644 qualtran/surface_code/algorithm_specs.py diff --git a/qualtran/surface_code/algorithm_specs.py b/qualtran/surface_code/algorithm_specs.py deleted file mode 100644 index 5ee8d1121..000000000 --- a/qualtran/surface_code/algorithm_specs.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -import attr -from attrs import frozen - -_PRETTY_FLOAT = attr.ib(type=float, default=0.0, repr=lambda x: f'{x:g}') - - -@frozen -class AlgorithmSpecs: - """Properties of a quantum algorithm that impact its physical cost - - Attributes: - algorithm_qubits: Number of qubits used by the algorithm. - measurements: Number of Measurements. - t_gates: Number of T gates. - toffoli_gates: Number of Toffoli gates. - rotation_gates: Number of Rotations. - rotation_circuit_depth: Depth of rotation circuit. - """ - - algorithm_qubits = _PRETTY_FLOAT # Number of algorithm qubits $Q_{alg}$ - measurements = _PRETTY_FLOAT # Number of measurements $M_R$. - t_gates = _PRETTY_FLOAT # Number of T gates $M_T$. - toffoli_gates = _PRETTY_FLOAT # Number of Toffoli gates $M_{Tof}$. - rotation_gates = _PRETTY_FLOAT # Number of Rotations $M_R$. - rotation_circuit_depth = _PRETTY_FLOAT # Depth of rotation circuit $D_R$.