-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
223 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
221 changes: 221 additions & 0 deletions
221
test/library/randomized_benchmarking/test_layer_fidelity.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2023. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
"""Test for layer fidelity experiments.""" | ||
import copy | ||
import numpy as np | ||
|
||
from test.base import QiskitExperimentsTestCase | ||
from test.library.randomized_benchmarking.mixin import RBTestMixin | ||
from ddt import ddt, data, unpack | ||
|
||
from qiskit.circuit.library import SXGate | ||
from qiskit.exceptions import QiskitError | ||
from qiskit.providers.fake_provider import FakeManilaV2 | ||
from qiskit.pulse import Schedule | ||
from qiskit_experiments.library.randomized_benchmarking import LayerFidelity, LayerFidelityAnalysis | ||
|
||
|
||
@ddt | ||
class TestLayerFidelity(QiskitExperimentsTestCase, RBTestMixin): | ||
"""Test for LayerFidelity without running the experiments.""" | ||
|
||
# ### Tests for configuration ### | ||
def test_experiment_config(self): | ||
"""Test converting to and from config works""" | ||
exp = LayerFidelity( | ||
physical_qubits=(0, 1, 2, 3), | ||
two_qubit_layers=[[(1, 0), (2, 3)], [(1, 2)]], | ||
lengths=[10, 20, 30], | ||
seed=42, | ||
two_qubit_gate="cx", | ||
one_qubit_basis_gates=["rz", "sx", "x"], | ||
) | ||
loaded_exp = LayerFidelity.from_config(exp.config()) | ||
self.assertNotEqual(exp, loaded_exp) | ||
self.assertEqualExtended(exp, loaded_exp) | ||
|
||
# def test_invalid_two_qubit_layers(self): | ||
# """Test raise error when creating experiment with invalid configs.""" | ||
# valid_kwargs = { | ||
# "lengths": [10, 20, 30], | ||
# "two_qubit_gate": "cx", | ||
# "one_qubit_basis_gates": ["rz", "sx", "x"], | ||
# } | ||
# # not disjoit | ||
# with self.assertRaises(QiskitError): | ||
# LayerFidelity( | ||
# physical_qubits=(0, 1, 2, 3), | ||
# two_qubit_layers=[[(0, 1), (1, 2)]], | ||
# **valid_kwargs | ||
# ) | ||
# # no 2q-gate on the qubits (FakeManilaV2 has no cx gate on (0, 3)) | ||
# with self.assertRaises(QiskitError): | ||
# LayerFidelity( | ||
# physical_qubits=(0, 1, 2, 3), | ||
# two_qubit_layers=[[(0, 3)]], | ||
# backend=FakeManilaV2(), | ||
# **valid_kwargs | ||
# ) | ||
|
||
def test_roundtrip_serializable(self): | ||
"""Test round trip JSON serialization""" | ||
exp = LayerFidelity( | ||
physical_qubits=(0, 1, 2, 3), | ||
two_qubit_layers=[[(1, 0), (2, 3)], [(1, 2)]], | ||
lengths=[10, 20, 30], | ||
seed=42, | ||
two_qubit_gate="cx", | ||
one_qubit_basis_gates=["rz", "sx", "x"], | ||
) | ||
self.assertRoundTripSerializable(exp, strict_type=False) | ||
|
||
def test_circuit_roundtrip_serializable(self): | ||
"""Test circuits round trip JSON serialization""" | ||
exp = LayerFidelity( | ||
physical_qubits=(0, 1, 2, 3), | ||
two_qubit_layers=[[(1, 0), (2, 3)], [(1, 2)]], | ||
lengths=[10, 20, 30], | ||
seed=42, | ||
two_qubit_gate="cx", | ||
one_qubit_basis_gates=["rz", "sx", "x"], | ||
) | ||
self.assertRoundTripSerializable(exp._transpiled_circuits()) | ||
|
||
def test_analysis_config(self): | ||
""" "Test converting analysis to and from config works""" | ||
analysis = LayerFidelityAnalysis(layers=[[(1, 0), (2, 3)], [(1, 2), (0,), (3,)]]) | ||
loaded = LayerFidelityAnalysis.from_config(analysis.config()) | ||
self.assertNotEqual(analysis, loaded) | ||
self.assertEqual(analysis.config(), loaded.config()) | ||
|
||
# ### Tests for circuit generation ### | ||
@data( | ||
[(1, 2), [[(1, 2)]]], | ||
[(1, 3, 4), [[(3, 4)]]], | ||
[(4, 3, 2, 1, 0), [[(0, 1), (3, 2)], [(1, 2), (3, 4)]]], | ||
) | ||
@unpack | ||
def test_generate_circuits(self, qubits, two_qubit_layers): | ||
"""Test RB circuit generation""" | ||
exp = LayerFidelity( | ||
physical_qubits=qubits, | ||
two_qubit_layers=two_qubit_layers, | ||
lengths=[1, 2, 3], | ||
seed=42, | ||
two_qubit_gate="cx", | ||
one_qubit_basis_gates=["rz", "sx", "x"], | ||
) | ||
circuits = exp.circuits() | ||
self.assertAllIdentity(circuits) | ||
|
||
def test_return_same_circuit_for_same_config(self): | ||
"""Test if setting the same seed returns the same circuits.""" | ||
exp1 = LayerFidelity( | ||
physical_qubits=(0, 1, 2, 3), | ||
two_qubit_layers=[[(1, 0), (2, 3)], [(1, 2)]], | ||
lengths=[10, 20, 30], | ||
seed=42, | ||
two_qubit_gate="cx", | ||
one_qubit_basis_gates=["rz", "sx", "x"], | ||
) | ||
|
||
exp2 = LayerFidelity( | ||
physical_qubits=(0, 1, 2, 3), | ||
two_qubit_layers=[[(1, 0), (2, 3)], [(1, 2)]], | ||
lengths=[10, 20, 30], | ||
seed=42, | ||
two_qubit_gate="cx", | ||
one_qubit_basis_gates=["rz", "sx", "x"], | ||
) | ||
|
||
circs1 = exp1.circuits() | ||
circs2 = exp2.circuits() | ||
|
||
self.assertEqual(circs1[0].decompose(), circs2[0].decompose()) | ||
self.assertEqual(circs1[1].decompose(), circs2[1].decompose()) | ||
self.assertEqual(circs1[2].decompose(), circs2[2].decompose()) | ||
|
||
# ### Tests for transpiled circuit generation ### | ||
def test_calibrations_via_custom_backend(self): | ||
"""Test if calibrations given as custom backend show up in transpiled circuits.""" | ||
qubits = (2,) | ||
my_sched = Schedule(name="custom_sx_gate") | ||
my_backend = copy.deepcopy(FakeManilaV2()) | ||
my_backend.target["sx"][qubits].calibration = my_sched | ||
|
||
exp = LayerFidelity( | ||
physical_qubits=(0, 1, 2, 3), | ||
two_qubit_layers=[[(1, 0), (2, 3)], [(1, 2)]], | ||
lengths=[10, 20, 30], | ||
seed=42, | ||
backend=my_backend, | ||
) | ||
transpiled = exp._transpiled_circuits() | ||
for qc in transpiled: | ||
self.assertTrue(qc.calibrations) | ||
self.assertTrue(qc.has_calibration_for((SXGate(), [qc.qubits[q] for q in qubits], []))) | ||
self.assertEqual(qc.calibrations["sx"][(qubits, tuple())], my_sched) | ||
|
||
def test_backend_with_directed_basis_gates(self): | ||
"""Test if correct circuits are generated from backend with directed basis gates.""" | ||
my_backend = copy.deepcopy(FakeManilaV2()) | ||
del my_backend.target["cx"][(1, 2)] # make cx on {1, 2} one-sided | ||
|
||
exp = LayerFidelity( | ||
physical_qubits=(0, 1, 2, 3), | ||
two_qubit_layers=[[(1, 0), (2, 3)], [(1, 2)]], | ||
lengths=[10, 20, 30], | ||
seed=42, | ||
backend=my_backend, | ||
) | ||
transpiled = exp._transpiled_circuits() | ||
for qc in transpiled: | ||
self.assertTrue(qc.count_ops().get("cx", 0) > 0) | ||
expected_qubits = (qc.qubits[2], qc.qubits[1]) | ||
for inst in qc: | ||
if inst.operation.name == "cx": | ||
self.assertEqual(inst.qubits, expected_qubits) | ||
|
||
|
||
class TestRunLayerFidelity(QiskitExperimentsTestCase, RBTestMixin): | ||
"""Test for running LayerFidelity on noisy simulator.""" | ||
|
||
def test_three_qubit(self): | ||
"""Test two qubit RB. Use default basis gates.""" | ||
exp = LayerFidelity( | ||
physical_qubits=(0, 1, 2, 3), | ||
two_qubit_layers=[[(1, 0), (2, 3)], [(1, 2)]], | ||
lengths=[1, 4, 16, 64, 256], | ||
seed=42, | ||
backend=FakeManilaV2(), | ||
) | ||
expdata = exp.run() | ||
self.assertExperimentDone(expdata) | ||
|
||
lf = expdata.analysis_results("LF").value.n | ||
slfs = [res.value.n for res in expdata.analysis_results("SingleLF")] | ||
self.assertAlmostEqual(lf, np.prod(slfs)) | ||
|
||
def test_expdata_serialization(self): | ||
"""Test serializing experiment data works.""" | ||
exp = LayerFidelity( | ||
physical_qubits=(0, 1, 2, 3), | ||
two_qubit_layers=[[(1, 0), (2, 3)], [(1, 2)]], | ||
lengths=[1, 4, 16, 64, 256], | ||
seed=42, | ||
backend=FakeManilaV2(), | ||
) | ||
expdata = exp.run() | ||
self.assertExperimentDone(expdata) | ||
self.assertRoundTripSerializable(expdata) | ||
self.assertRoundTripPickle(expdata) |