From e966c185b40ba2ee9032feff27b0310a0a9a0750 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 13 May 2021 12:29:45 +0300 Subject: [PATCH 01/22] Create test_rb.py --- test/test_rb.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 test/test_rb.py diff --git a/test/test_rb.py b/test/test_rb.py new file mode 100644 index 0000000000..02c70f56dd --- /dev/null +++ b/test/test_rb.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2021. +# +# 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. + +import numpy as np +import qiskit_experiments as qe +from qiskit.quantum_info import Clifford +from qiskit.test import QiskitTestCase +from numpy.random import Generator, default_rng +from typing import Union, Iterable, Optional +from qiskit.test.mock import FakeParis +import unittest +from qiskit.exceptions import QiskitError + + +@ddt +class TestRB(QiskitTestCase): + + @staticmethod + def RB_parameters_2_qubit(): + exp_data = {'qubits': [0, 1], 'lengths': [1, 3, 5, 7, 9], 'num_samples': 1, 'seed': 100} + rb = qe.randomized_benchmarking + RB_Test = rb.RBExperiment(exp_data["qubits"], exp_data["lengths"], num_samples=exp_data["num_samples"], + seed=exp_data["seed"]) + return exp_data, RB_Test + + def is_identity(self, circuits): + """Standard randomized benchmarking test - Identity check (assuming all the operator are spanned by clifford group) + Args: + quantum_Circuits: list of the circuits which we want to check + """ + + identity = True + for qc in circuits: + num_qubits = qc.num_qubits + qc.remove_final_measurements() + # Checking if the matrix representation is the identity matrix + self.assertEqual(np.allclose(Clifford(qc).to_matrix(), np.identity(2 ** num_qubits)), + 'Clifford sequence doesn\'t result in the identity matrix.') + # identity = identity and array_equal(a1, a2, equal_nan=False) + # self.assertEqual(identity, True,'Clifford sequence doesn\'t result in the identity matrix.') + + def validate_metadata(self, circuits, exp_data: dict): + """ + + Args: + circuits: + exp_data: + + Returns: + + """ + for ind, qc in enumerate(circuits): + self.assertEqual(qc.metadata['xdata'], self._lengths[ind], + 'The length of the experiment doen\'t match to the one provided.') + self.assertEqual(qc.metadata['qubits'], tuple(self._qubits[ind]), + 'The qubits indices doesn\'t match the ran qubit indices.') + + def test_RB_circuits(self): + exp_2_qubit_data_dict, exp_2_qubit_exp = self.RB_parameters_2_qubit() + exp_2_qubit_circ = exp_2_qubit_exp.circuits() + self.is_identity(exp_2_qubit_circ) + self.validate_metadata(exp_2_qubit_circ, exp_2_qubit_data_dict) + From e81f7a7371b32d3311bb71d388a497bd48532b1c Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 13 May 2021 15:18:52 +0300 Subject: [PATCH 02/22] Update test_rb.py --- test/test_rb.py | 85 +++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 02c70f56dd..ed083356d0 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -12,63 +12,80 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -import numpy as np + import qiskit_experiments as qe from qiskit.quantum_info import Clifford from qiskit.test import QiskitTestCase -from numpy.random import Generator, default_rng -from typing import Union, Iterable, Optional -from qiskit.test.mock import FakeParis -import unittest -from qiskit.exceptions import QiskitError +import numpy as np + +""" +Test RB experiment +""" -@ddt class TestRB(QiskitTestCase): + """ + A simple and primitive backend, to be run by the RB tests + """ @staticmethod - def RB_parameters_2_qubit(): - exp_data = {'qubits': [0, 1], 'lengths': [1, 3, 5, 7, 9], 'num_samples': 1, 'seed': 100} + def rb_parameters_2_qubit(): + """ + Initialize data for a RB experiment with specific parameters + Returns: + exp_data (Dictionary): A dictionary with the experiment setup. + rb_exp (RBExperiment): The instance for the experiment object. + """ + exp_data = {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100} rb = qe.randomized_benchmarking - RB_Test = rb.RBExperiment(exp_data["qubits"], exp_data["lengths"], num_samples=exp_data["num_samples"], - seed=exp_data["seed"]) - return exp_data, RB_Test + rb_exp = rb.RBExperiment( + exp_data["qubits"], + exp_data["lengths"], + num_samples=exp_data["num_samples"], + seed=exp_data["seed"], + ) + return exp_data, rb_exp - def is_identity(self, circuits): - """Standard randomized benchmarking test - Identity check (assuming all the operator are spanned by clifford group) + def is_identity(self, circuits: list): + """Standard randomized benchmarking test - Identity check + (assuming all the operator are spanned by clifford group) Args: - quantum_Circuits: list of the circuits which we want to check + circuits: list of the circuits which we want to check """ - - identity = True for qc in circuits: num_qubits = qc.num_qubits qc.remove_final_measurements() # Checking if the matrix representation is the identity matrix - self.assertEqual(np.allclose(Clifford(qc).to_matrix(), np.identity(2 ** num_qubits)), - 'Clifford sequence doesn\'t result in the identity matrix.') - # identity = identity and array_equal(a1, a2, equal_nan=False) - # self.assertEqual(identity, True,'Clifford sequence doesn\'t result in the identity matrix.') + self.assertEqual( + np.allclose(Clifford(qc).to_matrix(), np.identity(2 ** num_qubits)), + "Clifford sequence doesn't result in the identity matrix.", + ) - def validate_metadata(self, circuits, exp_data: dict): + def validate_metadata(self, circuits: list, exp_data: dict): """ - + Validate the fields in "metadata" for the experiment. Args: - circuits: - exp_data: - - Returns: - + circuits (list): A list containing quantum circuits + exp_data (dict): A dictionary with the experiment variable ands values """ for ind, qc in enumerate(circuits): - self.assertEqual(qc.metadata['xdata'], self._lengths[ind], - 'The length of the experiment doen\'t match to the one provided.') - self.assertEqual(qc.metadata['qubits'], tuple(self._qubits[ind]), - 'The qubits indices doesn\'t match the ran qubit indices.') + self.assertEqual( + qc.metadata["xdata"], + exp_data["lengths"][ind], + "The length of the experiment doen't match to the one provided.", + ) + self.assertEqual( + qc.metadata["qubits"], + tuple(exp_data["qubits"]), + "The qubits indices doesn't match the ran qubit indices.", + ) def test_RB_circuits(self): - exp_2_qubit_data_dict, exp_2_qubit_exp = self.RB_parameters_2_qubit() + """ + Run the RB test for the circuits (checking the metadata, parameters and functionallity + of the experiment. + """ + exp_2_qubit_data_dict, exp_2_qubit_exp = self.rb_parameters_2_qubit() exp_2_qubit_circ = exp_2_qubit_exp.circuits() self.is_identity(exp_2_qubit_circ) self.validate_metadata(exp_2_qubit_circ, exp_2_qubit_data_dict) - From 8d19a8b718a75052b3be930bcc10dbb924e323c0 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 13 May 2021 15:20:52 +0300 Subject: [PATCH 03/22] Update test_rb.py --- test/test_rb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_rb.py b/test/test_rb.py index ed083356d0..cdd76bbfc6 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -19,7 +19,7 @@ import numpy as np """ -Test RB experiment +A Tester for the RB experiment """ From 35751abb6c98152267df062a47b1dbbfde3760d9 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 13 May 2021 16:03:09 +0300 Subject: [PATCH 04/22] Update test_rb.py --- test/test_rb.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_rb.py b/test/test_rb.py index cdd76bbfc6..19c92668d6 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -58,6 +58,7 @@ def is_identity(self, circuits: list): # Checking if the matrix representation is the identity matrix self.assertEqual( np.allclose(Clifford(qc).to_matrix(), np.identity(2 ** num_qubits)), + True, "Clifford sequence doesn't result in the identity matrix.", ) From 9a5da89f45d90d1c42059ec65fcbd98ad4f8b19a Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 13 May 2021 17:01:47 +0300 Subject: [PATCH 05/22] Update test_rb.py --- test/test_rb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_rb.py b/test/test_rb.py index 19c92668d6..985df9e553 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -71,7 +71,7 @@ def validate_metadata(self, circuits: list, exp_data: dict): """ for ind, qc in enumerate(circuits): self.assertEqual( - qc.metadata["xdata"], + qc.metadata["xval"], exp_data["lengths"][ind], "The length of the experiment doen't match to the one provided.", ) From fc14de55b075cd2f260afcc2239b02bba05f3cdc Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 20 May 2021 15:55:12 +0300 Subject: [PATCH 06/22] Added Test to validate the circuit data Changed names of some variables to represent better their content, added return var for experiment results. Added Test to validate the circuit data with the experiment attribute. --- test/test_rb.py | 66 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 985df9e553..70b070d0bf 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -16,8 +16,10 @@ import qiskit_experiments as qe from qiskit.quantum_info import Clifford from qiskit.test import QiskitTestCase +from qiskit.test.mock import FakeParis import numpy as np + """ A Tester for the RB experiment """ @@ -33,18 +35,21 @@ def rb_parameters_2_qubit(): """ Initialize data for a RB experiment with specific parameters Returns: - exp_data (Dictionary): A dictionary with the experiment setup. + exp_attributes (Dictionary): A dictionary with the experiment setup attributes. rb_exp (RBExperiment): The instance for the experiment object. + exp_data (RBExperiment): The experiment data and results after it had run. """ - exp_data = {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100} + backend = FakeParis() + exp_attributes = {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100} rb = qe.randomized_benchmarking rb_exp = rb.RBExperiment( - exp_data["qubits"], - exp_data["lengths"], - num_samples=exp_data["num_samples"], - seed=exp_data["seed"], + exp_attributes["qubits"], + exp_attributes["lengths"], + num_samples=exp_attributes["num_samples"], + seed=exp_attributes["seed"], ) - return exp_data, rb_exp + exp_data = rb_exp.run(backend) + return exp_attributes, rb_exp, exp_data def is_identity(self, circuits: list): """Standard randomized benchmarking test - Identity check @@ -62,23 +67,48 @@ def is_identity(self, circuits: list): "Clifford sequence doesn't result in the identity matrix.", ) - def validate_metadata(self, circuits: list, exp_data: dict): + def validate_metadata(self, circuits: list, exp_attributes: dict): """ Validate the fields in "metadata" for the experiment. Args: circuits (list): A list containing quantum circuits - exp_data (dict): A dictionary with the experiment variable ands values + exp_attributes (dict): A dictionary with the experiment variable ands values """ for ind, qc in enumerate(circuits): self.assertEqual( qc.metadata["xval"], - exp_data["lengths"][ind], - "The length of the experiment doen't match to the one provided.", + exp_attributes["lengths"][ind], + "The number of gates in the experiment metadata doesn't match to the one provided.", ) self.assertEqual( qc.metadata["qubits"], - tuple(exp_data["qubits"]), - "The qubits indices doesn't match the ran qubit indices.", + tuple(exp_attributes["qubits"]), + "The qubits indices in the experiment metadata doesn't match to the one provided.", + ) + + def validate_circuit_data(self, experiment: qe.experiment_data.ExperimentData, + exp_attributes: dict): + """ + Validate that the metadata of the experiment after it had run matches the one provided. + Args: + experiment(qiskit_experiments.experiment_data.ExperimentData): The experiment + data and results after it run. + exp_attributes (dict): A dictionary with the experiment variable ands values + + Returns: + + """ + for ind, data in enumerate(experiment.data): + experiment_information = data['metadata'] + self.assertEqual( + experiment_information["xdata"], + exp_attributes["lengths"][ind], + "The number of gates in the experiment doesn't match to the one in the metadata.", + ) + self.assertEqual( + experiment_information["qubits"], + exp_attributes["qubits"], + "The qubits indices in the experiment doesn't match to the one in the metadata.", ) def test_RB_circuits(self): @@ -86,7 +116,9 @@ def test_RB_circuits(self): Run the RB test for the circuits (checking the metadata, parameters and functionallity of the experiment. """ - exp_2_qubit_data_dict, exp_2_qubit_exp = self.rb_parameters_2_qubit() - exp_2_qubit_circ = exp_2_qubit_exp.circuits() - self.is_identity(exp_2_qubit_circ) - self.validate_metadata(exp_2_qubit_circ, exp_2_qubit_data_dict) + exp_2_qubit_metadata_attributes_dict, exp_2_qubit_exp, exp_2_quibit_exp_data = self.rb_parameters_2_qubit() + exp_2_qubit_circuit = exp_2_qubit_exp.circuits() + self.is_identity(exp_2_qubit_circuit) + self.validate_metadata(exp_2_qubit_circuit, exp_2_qubit_metadata_attributes_dict) + self.validate_circuit_data(exp_2_quibit_exp_data, exp_2_qubit_metadata_attributes_dict) + From fa5199ae2c5a5b6ceaf9a53cea2cc0c3f7566cdb Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 20 May 2021 16:14:26 +0300 Subject: [PATCH 07/22] Lint fixed --- test/test_rb.py | 52 ++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 70b070d0bf..4aafe967fd 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -12,6 +12,9 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. +""" +A Tester for the RB experiment +""" import qiskit_experiments as qe from qiskit.quantum_info import Clifford @@ -20,27 +23,27 @@ import numpy as np -""" -A Tester for the RB experiment -""" - - class TestRB(QiskitTestCase): """ A simple and primitive backend, to be run by the RB tests """ @staticmethod - def rb_parameters_2_qubit(): + def rb_parameters_two_qubit(): """ Initialize data for a RB experiment with specific parameters Returns: - exp_attributes (Dictionary): A dictionary with the experiment setup attributes. - rb_exp (RBExperiment): The instance for the experiment object. - exp_data (RBExperiment): The experiment data and results after it had run. + dict: A dictionary with the experiment setup attributes. + RBExperiment: The instance for the experiment object. + ExperimentData: The experiment data and results after it had run. """ backend = FakeParis() - exp_attributes = {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100} + exp_attributes = { + "qubits": [0, 1], + "lengths": [1, 3, 5, 7, 9], + "num_samples": 1, + "seed": 100, + } rb = qe.randomized_benchmarking rb_exp = rb.RBExperiment( exp_attributes["qubits"], @@ -55,7 +58,7 @@ def is_identity(self, circuits: list): """Standard randomized benchmarking test - Identity check (assuming all the operator are spanned by clifford group) Args: - circuits: list of the circuits which we want to check + circuits (list): list of the circuits which we want to check """ for qc in circuits: num_qubits = qc.num_qubits @@ -86,20 +89,18 @@ def validate_metadata(self, circuits: list, exp_attributes: dict): "The qubits indices in the experiment metadata doesn't match to the one provided.", ) - def validate_circuit_data(self, experiment: qe.experiment_data.ExperimentData, - exp_attributes: dict): + def validate_circuit_data( + self, experiment: qe.experiment_data.ExperimentData, exp_attributes: dict + ): """ Validate that the metadata of the experiment after it had run matches the one provided. Args: - experiment(qiskit_experiments.experiment_data.ExperimentData): The experiment + experiment(qiskit_experiments.experiment_data.ExperimentData): The experiment data and results after it run. exp_attributes (dict): A dictionary with the experiment variable ands values - - Returns: - """ for ind, data in enumerate(experiment.data): - experiment_information = data['metadata'] + experiment_information = data["metadata"] self.assertEqual( experiment_information["xdata"], exp_attributes["lengths"][ind], @@ -116,9 +117,12 @@ def test_RB_circuits(self): Run the RB test for the circuits (checking the metadata, parameters and functionallity of the experiment. """ - exp_2_qubit_metadata_attributes_dict, exp_2_qubit_exp, exp_2_quibit_exp_data = self.rb_parameters_2_qubit() - exp_2_qubit_circuit = exp_2_qubit_exp.circuits() - self.is_identity(exp_2_qubit_circuit) - self.validate_metadata(exp_2_qubit_circuit, exp_2_qubit_metadata_attributes_dict) - self.validate_circuit_data(exp_2_quibit_exp_data, exp_2_qubit_metadata_attributes_dict) - + ( + exp_two_qubit_att_metadata, + exp_two_qubit_exp, + exp_two_quibit_exp_data, + ) = self.rb_parameters_two_qubit() + exp_two_qubit_circuit = exp_two_qubit_exp.circuits() + self.is_identity(exp_two_qubit_circuit) + self.validate_metadata(exp_two_qubit_circuit, exp_two_qubit_att_metadata) + self.validate_circuit_data(exp_two_quibit_exp_data, exp_two_qubit_att_metadata) From 7039b8e3427928ca54822d2a3a8d7b2656a2a8b0 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Mon, 24 May 2021 18:15:44 +0300 Subject: [PATCH 08/22] Added test for transpiled circuit Few things were changed: 1. There is a function for each test experiment configuration. 2. Added transpiled circuit check using process_fidelity from qiskit.quantum_info.operators.measures 3. Changed the np.allclose to matrix_equal function to be invariant for global phase. --- test/test_rb.py | 143 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 128 insertions(+), 15 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 4aafe967fd..791a28677b 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -17,9 +17,12 @@ """ import qiskit_experiments as qe +from qiskit.quantum_info.operators.predicates import matrix_equal from qiskit.quantum_info import Clifford from qiskit.test import QiskitTestCase from qiskit.test.mock import FakeParis +from qiskit.exceptions import QiskitError +from qiskit.quantum_info.operators.measures import process_fidelity import numpy as np @@ -28,10 +31,39 @@ class TestRB(QiskitTestCase): A simple and primitive backend, to be run by the RB tests """ - @staticmethod - def rb_parameters_two_qubit(): + def rb_parameters_one_qubit(self): """ - Initialize data for a RB experiment with specific parameters + Initialize data and executing RB experiment on one qubits with specific parameters + Returns: + dict: A dictionary with the experiment setup attributes. + RBExperiment: The instance for the experiment object. + ExperimentData: The experiment data and results after it had run. + """ + backend = FakeParis() + exp_attributes = { + "qubits": [1], + "lengths": [1, 3, 5, 7, 9], + "num_samples": 1, + "seed": 100, + } + rb = qe.randomized_benchmarking + rb_exp = rb.RBExperiment( + exp_attributes["qubits"], + exp_attributes["lengths"], + num_samples=exp_attributes["num_samples"], + seed=exp_attributes["seed"], + ) + exp_data = rb_exp.run(backend) + exp_circuit = rb_exp.circuits() + exp_transpiled_circuit = rb_exp.transpiled_circuits() + self.validate_metadata(exp_circuit, exp_attributes) + self.validate_circuit_data(exp_data, exp_attributes) + self.is_identity_transpiled(exp_transpiled_circuit) + self.is_identity(exp_circuit) + + def rb_parameters_two_qubit(self): + """ + Initialize data and executing RB experiment on two qubits with specific parameters Returns: dict: A dictionary with the experiment setup attributes. RBExperiment: The instance for the experiment object. @@ -52,10 +84,45 @@ def rb_parameters_two_qubit(): seed=exp_attributes["seed"], ) exp_data = rb_exp.run(backend) - return exp_attributes, rb_exp, exp_data + exp_circuit = rb_exp.circuits() + exp_transpiled_circuit = rb_exp.transpiled_circuits() + self.validate_metadata(exp_circuit, exp_attributes) + self.validate_circuit_data(exp_data, exp_attributes) + self.is_identity_transpiled(exp_transpiled_circuit) + self.is_identity(exp_circuit) + + def rb_parameters_three_qubit(self): + """ + Initialize data and executing RB experiment on three qubits with specific parameters + Returns: + dict: A dictionary with the experiment setup attributes. + RBExperiment: The instance for the experiment object. + ExperimentData: The experiment data and results after it had run. + """ + backend = FakeParis() + exp_attributes = { + "qubits": [0, 1, 2], + "lengths": [1, 3, 5, 7, 9], + "num_samples": 1, + "seed": 100, + } + rb = qe.randomized_benchmarking + rb_exp = rb.RBExperiment( + exp_attributes["qubits"], + exp_attributes["lengths"], + num_samples=exp_attributes["num_samples"], + seed=exp_attributes["seed"], + ) + exp_data = rb_exp.run(backend) + exp_circuit = rb_exp.circuits() + exp_transpiled_circuit = rb_exp.transpiled_circuits() + self.validate_metadata(exp_circuit, exp_attributes) + self.validate_circuit_data(exp_data, exp_attributes) + self.is_identity_transpiled(exp_transpiled_circuit) + self.is_identity(exp_circuit) def is_identity(self, circuits: list): - """Standard randomized benchmarking test - Identity check + """Standard randomized benchmarking test - Identity check. (assuming all the operator are spanned by clifford group) Args: circuits (list): list of the circuits which we want to check @@ -65,11 +132,27 @@ def is_identity(self, circuits: list): qc.remove_final_measurements() # Checking if the matrix representation is the identity matrix self.assertEqual( - np.allclose(Clifford(qc).to_matrix(), np.identity(2 ** num_qubits)), + matrix_equal(Clifford(qc).to_matrix(), np.identity(2 ** num_qubits)), True, "Clifford sequence doesn't result in the identity matrix.", ) + def is_identity_transpiled(self, transpiled_circuits: list): + """Standard randomized benchmarking test - Identity check for the transpiled circuits. + Using + Args: + transpiled_circuits (list): list of the circuits which we want to check + """ + for qc in transpiled_circuits: + num_qubits = qc.num_qubits + qc.remove_final_measurements() + # Checking if the matrix representation is the identity matrix + self.assertAlmostEqual( + process_fidelity(Clifford(qc).to_matrix(), np.identity(2 ** num_qubits)), + 1, + "Transpiled circuit doesn't result in the identity operator.", + ) + def validate_metadata(self, circuits: list, exp_attributes: dict): """ Validate the fields in "metadata" for the experiment. @@ -95,6 +178,7 @@ def validate_circuit_data( """ Validate that the metadata of the experiment after it had run matches the one provided. Args: + experiment(qiskit_experiments.experiment_data.ExperimentData): The experiment data and results after it run. exp_attributes (dict): A dictionary with the experiment variable ands values @@ -112,17 +196,46 @@ def validate_circuit_data( "The qubits indices in the experiment doesn't match to the one in the metadata.", ) + def _exp_data_prpeties(self): + """ + Return a list of dictionaries that contains invalid experiment propeties to check errors. + """ + exp_data_list = [ + {"qubits": [3, 3], "lengths": [1, 3, 5, 7, 9], "num_samples": 0, "seed": 100}, + {"qubits": [-1], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100}, + {"qubits": [0, 1], "lengths": [1, 3, 5, -7, 9], "num_samples": 1, "seed": 100}, + {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": -4, "seed": 100}, + {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": 0, "seed": 100}, + {"qubits": [0, 1], "lengths": [1, 5, 5, 5, 9], "num_samples": 0, "seed": 100}, + ] + return exp_data_list + + def _test_input(self): + """ + Check that errors emerge when invalid input is given to the RB experiment. + """ + exp_data_list = self._exp_data_prpeties() + rb = qe.randomized_benchmarking + for exp_data in exp_data_list: + self.assertRaises( + QiskitError, + rb.RBExperiment, + exp_data["qubits"], + exp_data["lengths"], + num_samples=exp_data["num_samples"], + seed=exp_data["seed"], + ) + def test_RB_circuits(self): """ Run the RB test for the circuits (checking the metadata, parameters and functionallity of the experiment. """ - ( - exp_two_qubit_att_metadata, - exp_two_qubit_exp, - exp_two_quibit_exp_data, - ) = self.rb_parameters_two_qubit() - exp_two_qubit_circuit = exp_two_qubit_exp.circuits() - self.is_identity(exp_two_qubit_circuit) - self.validate_metadata(exp_two_qubit_circuit, exp_two_qubit_att_metadata) - self.validate_circuit_data(exp_two_quibit_exp_data, exp_two_qubit_att_metadata) + self._test_input() + self.rb_parameters_one_qubit() + self.rb_parameters_two_qubit() + self.rb_parameters_three_qubit() + + +tmp = TestRB() +tmp.test_RB_circuits() From 89a82fd2b1f1a579821b7ee84b81ed51a0626783 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Mon, 24 May 2021 18:44:33 +0300 Subject: [PATCH 09/22] Update test_rb.py --- test/test_rb.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 791a28677b..9262760cee 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -231,11 +231,7 @@ def test_RB_circuits(self): Run the RB test for the circuits (checking the metadata, parameters and functionallity of the experiment. """ - self._test_input() + # self._test_input() self.rb_parameters_one_qubit() self.rb_parameters_two_qubit() self.rb_parameters_three_qubit() - - -tmp = TestRB() -tmp.test_RB_circuits() From 077e8186b0d73764f11361223dfe48d2cff3290d Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Mon, 24 May 2021 18:50:06 +0300 Subject: [PATCH 10/22] Update test_rb.py --- test/test_rb.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 9262760cee..72a9354088 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -16,14 +16,15 @@ A Tester for the RB experiment """ -import qiskit_experiments as qe from qiskit.quantum_info.operators.predicates import matrix_equal from qiskit.quantum_info import Clifford +from qiskit.quantum_info.operators.measures import process_fidelity from qiskit.test import QiskitTestCase from qiskit.test.mock import FakeParis from qiskit.exceptions import QiskitError -from qiskit.quantum_info.operators.measures import process_fidelity import numpy as np +import qiskit_experiments as qe + class TestRB(QiskitTestCase): From cd49a18b7cfe93f0a464a80177fd70edbdc43421 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Mon, 24 May 2021 18:55:19 +0300 Subject: [PATCH 11/22] Black and lint --- test/test_rb.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_rb.py b/test/test_rb.py index 72a9354088..90df595f6d 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -26,7 +26,6 @@ import qiskit_experiments as qe - class TestRB(QiskitTestCase): """ A simple and primitive backend, to be run by the RB tests From dd13ed0168b57320cb361cec908038a8b7c0ab9f Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Mon, 24 May 2021 19:05:39 +0300 Subject: [PATCH 12/22] uncommented test --- test/test_rb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_rb.py b/test/test_rb.py index 90df595f6d..116aee020a 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -231,7 +231,7 @@ def test_RB_circuits(self): Run the RB test for the circuits (checking the metadata, parameters and functionallity of the experiment. """ - # self._test_input() + self._test_input() self.rb_parameters_one_qubit() self.rb_parameters_two_qubit() self.rb_parameters_three_qubit() From 118f133830c100c3e01e01f14aeeb00c284ca1d2 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 27 May 2021 11:32:25 +0300 Subject: [PATCH 13/22] Changes in experiment attributes Changed some experiment attributes. Added comment why every configuration that return by _exp_data_properties() should raise an exception. --- .gitignore | 1 + test/test_rb.py | 74 +++++++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index b3d4b6bfd7..28f40a879a 100644 --- a/.gitignore +++ b/.gitignore @@ -147,3 +147,4 @@ docs/stubs/* test/ipynb/mpl/*.png test/ipynb/mpl/*.zip test/ipynb/mpl/result_test.json +test/Debug_RB.py diff --git a/test/test_rb.py b/test/test_rb.py index 116aee020a..78f136a10e 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -19,6 +19,7 @@ from qiskit.quantum_info.operators.predicates import matrix_equal from qiskit.quantum_info import Clifford from qiskit.quantum_info.operators.measures import process_fidelity +import qiskit.quantum_info.operators as op from qiskit.test import QiskitTestCase from qiskit.test.mock import FakeParis from qiskit.exceptions import QiskitError @@ -28,21 +29,17 @@ class TestRB(QiskitTestCase): """ - A simple and primitive backend, to be run by the RB tests + A test class for the RB Experiment to check that the RBExperiment class is working correctly. """ def rb_parameters_one_qubit(self): """ - Initialize data and executing RB experiment on one qubits with specific parameters - Returns: - dict: A dictionary with the experiment setup attributes. - RBExperiment: The instance for the experiment object. - ExperimentData: The experiment data and results after it had run. + Initializes data and executes an RB experiment on one qubit with specific parameters """ backend = FakeParis() exp_attributes = { - "qubits": [1], - "lengths": [1, 3, 5, 7, 9], + "qubits": [3], + "lengths": [1, 4, 6, 9, 13, 16], "num_samples": 1, "seed": 100, } @@ -54,25 +51,21 @@ def rb_parameters_one_qubit(self): seed=exp_attributes["seed"], ) exp_data = rb_exp.run(backend) - exp_circuit = rb_exp.circuits() + exp_circuits = rb_exp.circuits() exp_transpiled_circuit = rb_exp.transpiled_circuits() - self.validate_metadata(exp_circuit, exp_attributes) + self.validate_metadata(exp_circuits, exp_attributes) self.validate_circuit_data(exp_data, exp_attributes) self.is_identity_transpiled(exp_transpiled_circuit) - self.is_identity(exp_circuit) + self.is_identity(exp_circuits) def rb_parameters_two_qubit(self): """ - Initialize data and executing RB experiment on two qubits with specific parameters - Returns: - dict: A dictionary with the experiment setup attributes. - RBExperiment: The instance for the experiment object. - ExperimentData: The experiment data and results after it had run. + Initializes data and executes an RB experiment on two qubits with specific parameters """ backend = FakeParis() exp_attributes = { - "qubits": [0, 1], - "lengths": [1, 3, 5, 7, 9], + "qubits": [4, 7], + "lengths": [1, 4, 6, 9, 13, 16], "num_samples": 1, "seed": 100, } @@ -84,25 +77,21 @@ def rb_parameters_two_qubit(self): seed=exp_attributes["seed"], ) exp_data = rb_exp.run(backend) - exp_circuit = rb_exp.circuits() + exp_circuits = rb_exp.circuits() exp_transpiled_circuit = rb_exp.transpiled_circuits() - self.validate_metadata(exp_circuit, exp_attributes) + self.validate_metadata(exp_circuits, exp_attributes) self.validate_circuit_data(exp_data, exp_attributes) self.is_identity_transpiled(exp_transpiled_circuit) - self.is_identity(exp_circuit) + self.is_identity(exp_circuits) def rb_parameters_three_qubit(self): """ - Initialize data and executing RB experiment on three qubits with specific parameters - Returns: - dict: A dictionary with the experiment setup attributes. - RBExperiment: The instance for the experiment object. - ExperimentData: The experiment data and results after it had run. + Initializes data and executes an RB experiment on three qubits with specific parameters """ backend = FakeParis() exp_attributes = { - "qubits": [0, 1, 2], - "lengths": [1, 3, 5, 7, 9], + "qubits": [0, 5, 3], + "lengths": [1, 4, 6, 9, 13, 16], "num_samples": 1, "seed": 100, } @@ -114,12 +103,12 @@ def rb_parameters_three_qubit(self): seed=exp_attributes["seed"], ) exp_data = rb_exp.run(backend) - exp_circuit = rb_exp.circuits() + exp_circuits = rb_exp.circuits() exp_transpiled_circuit = rb_exp.transpiled_circuits() - self.validate_metadata(exp_circuit, exp_attributes) + self.validate_metadata(exp_circuits, exp_attributes) self.validate_circuit_data(exp_data, exp_attributes) self.is_identity_transpiled(exp_transpiled_circuit) - self.is_identity(exp_circuit) + self.is_identity(exp_circuits) def is_identity(self, circuits: list): """Standard randomized benchmarking test - Identity check. @@ -148,7 +137,7 @@ def is_identity_transpiled(self, transpiled_circuits: list): qc.remove_final_measurements() # Checking if the matrix representation is the identity matrix self.assertAlmostEqual( - process_fidelity(Clifford(qc).to_matrix(), np.identity(2 ** num_qubits)), + process_fidelity(op.Operator(qc).data, np.identity(2 ** num_qubits)), 1, "Transpiled circuit doesn't result in the identity operator.", ) @@ -158,7 +147,7 @@ def validate_metadata(self, circuits: list, exp_attributes: dict): Validate the fields in "metadata" for the experiment. Args: circuits (list): A list containing quantum circuits - exp_attributes (dict): A dictionary with the experiment variable ands values + exp_attributes (dict): A dictionary with the experiment variable and values """ for ind, qc in enumerate(circuits): self.assertEqual( @@ -178,15 +167,14 @@ def validate_circuit_data( """ Validate that the metadata of the experiment after it had run matches the one provided. Args: - experiment(qiskit_experiments.experiment_data.ExperimentData): The experiment data and results after it run. - exp_attributes (dict): A dictionary with the experiment variable ands values + exp_attributes (dict): A dictionary with the experiment variable and values """ for ind, data in enumerate(experiment.data): experiment_information = data["metadata"] self.assertEqual( - experiment_information["xdata"], + experiment_information["xval"], exp_attributes["lengths"][ind], "The number of gates in the experiment doesn't match to the one in the metadata.", ) @@ -196,12 +184,19 @@ def validate_circuit_data( "The qubits indices in the experiment doesn't match to the one in the metadata.", ) - def _exp_data_prpeties(self): + def _exp_data_properties(self): """ Return a list of dictionaries that contains invalid experiment propeties to check errors. + The dict have invalid data in them as the following: + exp_data_list[1]: same index of qubit. + exp_data_list[2]: qubit index is negative. + exp_data_list[3]: the length of the sequence has negative number. + exp_data_list[4]: num of samples is negative. + exp_data_list[5]: num of samples is 0. + exp_data_list[6]: the length of the sequence list has duplicates. """ exp_data_list = [ - {"qubits": [3, 3], "lengths": [1, 3, 5, 7, 9], "num_samples": 0, "seed": 100}, + {"qubits": [3, 3], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100}, {"qubits": [-1], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100}, {"qubits": [0, 1], "lengths": [1, 3, 5, -7, 9], "num_samples": 1, "seed": 100}, {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": -4, "seed": 100}, @@ -214,7 +209,7 @@ def _test_input(self): """ Check that errors emerge when invalid input is given to the RB experiment. """ - exp_data_list = self._exp_data_prpeties() + exp_data_list = self._exp_data_properties() rb = qe.randomized_benchmarking for exp_data in exp_data_list: self.assertRaises( @@ -235,3 +230,4 @@ def test_RB_circuits(self): self.rb_parameters_one_qubit() self.rb_parameters_two_qubit() self.rb_parameters_three_qubit() + From 72915889ec9623993abb3193460149c1c610e313 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 27 May 2021 14:15:57 +0300 Subject: [PATCH 14/22] Added ddt decorator and use it to decrease the number of functions Added decorator to make one function that test for different data (In this case: number of qubits) --- test/__init__.py | 27 +++++++++++++++++ test/test_rb.py | 79 ++++++------------------------------------------ 2 files changed, 37 insertions(+), 69 deletions(-) diff --git a/test/__init__.py b/test/__init__.py index e69de29bb2..57d628eca3 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -0,0 +1,27 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2017. +# +# 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. + +from ddt import data, unpack +from qiskit.test.utils import generate_cases + + +def combine(**kwargs): + """Decorator to create combinations and tests + @combine(level=[0, 1, 2, 3], + circuit=[a, b, c, d], + dsc='Test circuit {circuit.__name__} with level {level}', + name='{circuit.__name__}_level{level}') + """ + + def deco(func): + return data(*generate_cases(docstring=func.__doc__, **kwargs))(unpack(func)) + return deco diff --git a/test/test_rb.py b/test/test_rb.py index 78f136a10e..034ba20ade 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -23,74 +23,26 @@ from qiskit.test import QiskitTestCase from qiskit.test.mock import FakeParis from qiskit.exceptions import QiskitError +from ddt import ddt, data +from qiskit.test import utils import numpy as np import qiskit_experiments as qe - +@ddt class TestRB(QiskitTestCase): """ - A test class for the RB Experiment to check that the RBExperiment class is working correctly. + A test class for the RB Experiment to check that the RBExperiment class is working correctly. """ - def rb_parameters_one_qubit(self): - """ - Initializes data and executes an RB experiment on one qubit with specific parameters - """ - backend = FakeParis() - exp_attributes = { - "qubits": [3], - "lengths": [1, 4, 6, 9, 13, 16], - "num_samples": 1, - "seed": 100, - } - rb = qe.randomized_benchmarking - rb_exp = rb.RBExperiment( - exp_attributes["qubits"], - exp_attributes["lengths"], - num_samples=exp_attributes["num_samples"], - seed=exp_attributes["seed"], - ) - exp_data = rb_exp.run(backend) - exp_circuits = rb_exp.circuits() - exp_transpiled_circuit = rb_exp.transpiled_circuits() - self.validate_metadata(exp_circuits, exp_attributes) - self.validate_circuit_data(exp_data, exp_attributes) - self.is_identity_transpiled(exp_transpiled_circuit) - self.is_identity(exp_circuits) - - def rb_parameters_two_qubit(self): + @data(qubits=([3], [4, 7], [0, 5, 3])) + def test_rb_experiment(self, qubits): """ - Initializes data and executes an RB experiment on two qubits with specific parameters + Run the RB test for circuits (checking the metadata, parameters and functionallity + of the experiment) for different number of qubits. """ backend = FakeParis() exp_attributes = { - "qubits": [4, 7], - "lengths": [1, 4, 6, 9, 13, 16], - "num_samples": 1, - "seed": 100, - } - rb = qe.randomized_benchmarking - rb_exp = rb.RBExperiment( - exp_attributes["qubits"], - exp_attributes["lengths"], - num_samples=exp_attributes["num_samples"], - seed=exp_attributes["seed"], - ) - exp_data = rb_exp.run(backend) - exp_circuits = rb_exp.circuits() - exp_transpiled_circuit = rb_exp.transpiled_circuits() - self.validate_metadata(exp_circuits, exp_attributes) - self.validate_circuit_data(exp_data, exp_attributes) - self.is_identity_transpiled(exp_transpiled_circuit) - self.is_identity(exp_circuits) - - def rb_parameters_three_qubit(self): - """ - Initializes data and executes an RB experiment on three qubits with specific parameters - """ - backend = FakeParis() - exp_attributes = { - "qubits": [0, 5, 3], + "qubits": qubits, "lengths": [1, 4, 6, 9, 13, 16], "num_samples": 1, "seed": 100, @@ -205,7 +157,7 @@ def _exp_data_properties(self): ] return exp_data_list - def _test_input(self): + def test_input(self): """ Check that errors emerge when invalid input is given to the RB experiment. """ @@ -220,14 +172,3 @@ def _test_input(self): num_samples=exp_data["num_samples"], seed=exp_data["seed"], ) - - def test_RB_circuits(self): - """ - Run the RB test for the circuits (checking the metadata, parameters and functionallity - of the experiment. - """ - self._test_input() - self.rb_parameters_one_qubit() - self.rb_parameters_two_qubit() - self.rb_parameters_three_qubit() - From 45e3d66489b4516e8c8d098badc753159964c8cb Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 27 May 2021 14:17:49 +0300 Subject: [PATCH 15/22] Deleted the test for the transpiled circuit Deleted the test for the transpiled circuit since the function doesn't exist anymore --- test/test_rb.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 034ba20ade..de809da462 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -56,10 +56,8 @@ def test_rb_experiment(self, qubits): ) exp_data = rb_exp.run(backend) exp_circuits = rb_exp.circuits() - exp_transpiled_circuit = rb_exp.transpiled_circuits() self.validate_metadata(exp_circuits, exp_attributes) self.validate_circuit_data(exp_data, exp_attributes) - self.is_identity_transpiled(exp_transpiled_circuit) self.is_identity(exp_circuits) def is_identity(self, circuits: list): @@ -78,22 +76,6 @@ def is_identity(self, circuits: list): "Clifford sequence doesn't result in the identity matrix.", ) - def is_identity_transpiled(self, transpiled_circuits: list): - """Standard randomized benchmarking test - Identity check for the transpiled circuits. - Using - Args: - transpiled_circuits (list): list of the circuits which we want to check - """ - for qc in transpiled_circuits: - num_qubits = qc.num_qubits - qc.remove_final_measurements() - # Checking if the matrix representation is the identity matrix - self.assertAlmostEqual( - process_fidelity(op.Operator(qc).data, np.identity(2 ** num_qubits)), - 1, - "Transpiled circuit doesn't result in the identity operator.", - ) - def validate_metadata(self, circuits: list, exp_attributes: dict): """ Validate the fields in "metadata" for the experiment. From 2c6a9caf0f0ddcf3733097f676ae8d012988671f Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 27 May 2021 15:02:22 +0300 Subject: [PATCH 16/22] Ran Black on the code --- test/test_rb.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index de809da462..4afb59dbac 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -18,16 +18,14 @@ from qiskit.quantum_info.operators.predicates import matrix_equal from qiskit.quantum_info import Clifford -from qiskit.quantum_info.operators.measures import process_fidelity -import qiskit.quantum_info.operators as op from qiskit.test import QiskitTestCase from qiskit.test.mock import FakeParis from qiskit.exceptions import QiskitError from ddt import ddt, data -from qiskit.test import utils import numpy as np import qiskit_experiments as qe + @ddt class TestRB(QiskitTestCase): """ @@ -35,10 +33,11 @@ class TestRB(QiskitTestCase): """ @data(qubits=([3], [4, 7], [0, 5, 3])) - def test_rb_experiment(self, qubits): + def test_rb_experiment(self, qubits: list): """ - Run the RB test for circuits (checking the metadata, parameters and functionallity - of the experiment) for different number of qubits. + Initializes data and executes an RB experiment with specific parameters. + Args: + qubits (list): A list containing qubit indices for the experiment """ backend = FakeParis() exp_attributes = { @@ -120,14 +119,16 @@ def validate_circuit_data( def _exp_data_properties(self): """ - Return a list of dictionaries that contains invalid experiment propeties to check errors. - The dict have invalid data in them as the following: + Creates a list of dictionaries that contains invalid experiment properties to check errors. + The dict invalid data is as following: exp_data_list[1]: same index of qubit. exp_data_list[2]: qubit index is negative. exp_data_list[3]: the length of the sequence has negative number. exp_data_list[4]: num of samples is negative. exp_data_list[5]: num of samples is 0. exp_data_list[6]: the length of the sequence list has duplicates. + Returns: + list[dict]: list of dictionaries with experiment properties. """ exp_data_list = [ {"qubits": [3, 3], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100}, From 273a59243099fc6adc5db191c810ad4c816e3f83 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 27 May 2021 15:08:19 +0300 Subject: [PATCH 17/22] The test_rb.py passed lint (local) --- test/test_rb.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 4afb59dbac..15abe351e1 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -32,7 +32,7 @@ class TestRB(QiskitTestCase): A test class for the RB Experiment to check that the RBExperiment class is working correctly. """ - @data(qubits=([3], [4, 7], [0, 5, 3])) + @data([3], [4, 7], [0, 5, 3]) def test_rb_experiment(self, qubits: list): """ Initializes data and executes an RB experiment with specific parameters. @@ -104,8 +104,8 @@ def validate_circuit_data( data and results after it run. exp_attributes (dict): A dictionary with the experiment variable and values """ - for ind, data in enumerate(experiment.data): - experiment_information = data["metadata"] + for ind, exp_data in enumerate(experiment.data): + experiment_information = exp_data["metadata"] self.assertEqual( experiment_information["xval"], exp_attributes["lengths"][ind], From 34e4696064a2c591455467f94a348c745124d065 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 27 May 2021 15:10:26 +0300 Subject: [PATCH 18/22] Update __init__.py --- test/__init__.py | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/test/__init__.py b/test/__init__.py index 57d628eca3..e69de29bb2 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -1,27 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017. -# -# 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. - -from ddt import data, unpack -from qiskit.test.utils import generate_cases - - -def combine(**kwargs): - """Decorator to create combinations and tests - @combine(level=[0, 1, 2, 3], - circuit=[a, b, c, d], - dsc='Test circuit {circuit.__name__} with level {level}', - name='{circuit.__name__}_level{level}') - """ - - def deco(func): - return data(*generate_cases(docstring=func.__doc__, **kwargs))(unpack(func)) - return deco From 1708cfde92b49e8b9b7c41be4a43ab0f280aba0a Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 27 May 2021 18:05:46 +0300 Subject: [PATCH 19/22] Fixed the test for metadata and run experiment --- requirements-dev.txt | 7 +++++++ test/test_rb.py | 50 ++++++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index cc2c77b04c..1e4aa6c841 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,3 +10,10 @@ pygments>=2.4 reno>=3.2.0 sphinx-panels nbsphinx + +numpy~=1.19.2 +qiskit~=0.25.3 +ddt~=1.4.2 +setuptools~=56.1.0 +scipy~=1.5.2 +matplotlib~=3.3.2 \ No newline at end of file diff --git a/test/test_rb.py b/test/test_rb.py index 15abe351e1..72200ad348 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -21,7 +21,7 @@ from qiskit.test import QiskitTestCase from qiskit.test.mock import FakeParis from qiskit.exceptions import QiskitError -from ddt import ddt, data +from ddt import ddt, data, unpack import numpy as np import qiskit_experiments as qe @@ -32,7 +32,8 @@ class TestRB(QiskitTestCase): A test class for the RB Experiment to check that the RBExperiment class is working correctly. """ - @data([3], [4, 7], [0, 5, 3]) + @data([[3]], [[4, 7]], [[0, 5, 3]]) + @unpack def test_rb_experiment(self, qubits: list): """ Initializes data and executes an RB experiment with specific parameters. @@ -53,7 +54,8 @@ def test_rb_experiment(self, qubits: list): num_samples=exp_attributes["num_samples"], seed=exp_attributes["seed"], ) - exp_data = rb_exp.run(backend) + experiment_obj = rb_exp.run(backend) + exp_data = experiment_obj.experiment exp_circuits = rb_exp.circuits() self.validate_metadata(exp_circuits, exp_attributes) self.validate_circuit_data(exp_data, exp_attributes) @@ -69,9 +71,8 @@ def is_identity(self, circuits: list): num_qubits = qc.num_qubits qc.remove_final_measurements() # Checking if the matrix representation is the identity matrix - self.assertEqual( + self.assertTrue( matrix_equal(Clifford(qc).to_matrix(), np.identity(2 ** num_qubits)), - True, "Clifford sequence doesn't result in the identity matrix.", ) @@ -83,39 +84,42 @@ def validate_metadata(self, circuits: list, exp_attributes: dict): exp_attributes (dict): A dictionary with the experiment variable and values """ for ind, qc in enumerate(circuits): - self.assertEqual( - qc.metadata["xval"], + self.assertTrue( + qc.metadata["xval"] == exp_attributes["lengths"][ind], "The number of gates in the experiment metadata doesn't match to the one provided.", ) - self.assertEqual( - qc.metadata["qubits"], + self.assertTrue( + qc.metadata["qubits"] == tuple(exp_attributes["qubits"]), "The qubits indices in the experiment metadata doesn't match to the one provided.", ) def validate_circuit_data( - self, experiment: qe.experiment_data.ExperimentData, exp_attributes: dict + self, experiment: qe.randomized_benchmarking.rb_experiment.RBExperiment, exp_attributes: dict ): """ Validate that the metadata of the experiment after it had run matches the one provided. Args: - experiment(qiskit_experiments.experiment_data.ExperimentData): The experiment + experiment(qiskit_experiments..randomized_benchmarking.rb_experiment.RBExperiment): The experiment data and results after it run. exp_attributes (dict): A dictionary with the experiment variable and values """ - for ind, exp_data in enumerate(experiment.data): - experiment_information = exp_data["metadata"] - self.assertEqual( - experiment_information["xval"], - exp_attributes["lengths"][ind], - "The number of gates in the experiment doesn't match to the one in the metadata.", - ) - self.assertEqual( - experiment_information["qubits"], - exp_attributes["qubits"], - "The qubits indices in the experiment doesn't match to the one in the metadata.", - ) + self.assertTrue( + exp_attributes["lengths"] == + experiment.experiment_options.lengths, + "The number of gates in the experiment doesn't match to the one in the metadata.", + ) + self.assertTrue( + exp_attributes["num_samples"] == + experiment.experiment_options.num_samples, + "The number of samples in the experiment doesn't match to the one in the metadata.", + ) + self.assertTrue( + tuple(exp_attributes["qubits"]) == + experiment.physical_qubits, + "The qubits indices in the experiment doesn't match to the one in the metadata.", + ) def _exp_data_properties(self): """ From 371ecfcd2d2e12547fc75a25e22830d0e2b332aa Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 27 May 2021 18:08:34 +0300 Subject: [PATCH 20/22] Run Black --- test/test_rb.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 72200ad348..7b1cee33c3 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -85,18 +85,18 @@ def validate_metadata(self, circuits: list, exp_attributes: dict): """ for ind, qc in enumerate(circuits): self.assertTrue( - qc.metadata["xval"] == - exp_attributes["lengths"][ind], + qc.metadata["xval"] == exp_attributes["lengths"][ind], "The number of gates in the experiment metadata doesn't match to the one provided.", ) self.assertTrue( - qc.metadata["qubits"] == - tuple(exp_attributes["qubits"]), + qc.metadata["qubits"] == tuple(exp_attributes["qubits"]), "The qubits indices in the experiment metadata doesn't match to the one provided.", ) def validate_circuit_data( - self, experiment: qe.randomized_benchmarking.rb_experiment.RBExperiment, exp_attributes: dict + self, + experiment: qe.randomized_benchmarking.rb_experiment.RBExperiment, + exp_attributes: dict, ): """ Validate that the metadata of the experiment after it had run matches the one provided. @@ -106,18 +106,15 @@ def validate_circuit_data( exp_attributes (dict): A dictionary with the experiment variable and values """ self.assertTrue( - exp_attributes["lengths"] == - experiment.experiment_options.lengths, + exp_attributes["lengths"] == experiment.experiment_options.lengths, "The number of gates in the experiment doesn't match to the one in the metadata.", ) self.assertTrue( - exp_attributes["num_samples"] == - experiment.experiment_options.num_samples, + exp_attributes["num_samples"] == experiment.experiment_options.num_samples, "The number of samples in the experiment doesn't match to the one in the metadata.", ) self.assertTrue( - tuple(exp_attributes["qubits"]) == - experiment.physical_qubits, + tuple(exp_attributes["qubits"]) == experiment.physical_qubits, "The qubits indices in the experiment doesn't match to the one in the metadata.", ) From ef92925656ed04c143062c53d1f766d61b094f25 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Thu, 27 May 2021 18:15:10 +0300 Subject: [PATCH 21/22] Fixed lint --- test/test_rb.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 7b1cee33c3..4ccc25a33a 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -101,8 +101,7 @@ def validate_circuit_data( """ Validate that the metadata of the experiment after it had run matches the one provided. Args: - experiment(qiskit_experiments..randomized_benchmarking.rb_experiment.RBExperiment): The experiment - data and results after it run. + experiment: The experiment data and results after it run exp_attributes (dict): A dictionary with the experiment variable and values """ self.assertTrue( From f3f6f27a275517db5482e7a4242b53936c6dc118 Mon Sep 17 00:00:00 2001 From: Itamar Goldman Date: Sun, 30 May 2021 13:32:57 +0300 Subject: [PATCH 22/22] Deleted - Test for input error hadling Two function that were for the input test were deleted. No need to import QiskitError --- test/test_rb.py | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/test/test_rb.py b/test/test_rb.py index 4ccc25a33a..99a49729c5 100644 --- a/test/test_rb.py +++ b/test/test_rb.py @@ -20,7 +20,6 @@ from qiskit.quantum_info import Clifford from qiskit.test import QiskitTestCase from qiskit.test.mock import FakeParis -from qiskit.exceptions import QiskitError from ddt import ddt, data, unpack import numpy as np import qiskit_experiments as qe @@ -116,42 +115,3 @@ def validate_circuit_data( tuple(exp_attributes["qubits"]) == experiment.physical_qubits, "The qubits indices in the experiment doesn't match to the one in the metadata.", ) - - def _exp_data_properties(self): - """ - Creates a list of dictionaries that contains invalid experiment properties to check errors. - The dict invalid data is as following: - exp_data_list[1]: same index of qubit. - exp_data_list[2]: qubit index is negative. - exp_data_list[3]: the length of the sequence has negative number. - exp_data_list[4]: num of samples is negative. - exp_data_list[5]: num of samples is 0. - exp_data_list[6]: the length of the sequence list has duplicates. - Returns: - list[dict]: list of dictionaries with experiment properties. - """ - exp_data_list = [ - {"qubits": [3, 3], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100}, - {"qubits": [-1], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100}, - {"qubits": [0, 1], "lengths": [1, 3, 5, -7, 9], "num_samples": 1, "seed": 100}, - {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": -4, "seed": 100}, - {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": 0, "seed": 100}, - {"qubits": [0, 1], "lengths": [1, 5, 5, 5, 9], "num_samples": 0, "seed": 100}, - ] - return exp_data_list - - def test_input(self): - """ - Check that errors emerge when invalid input is given to the RB experiment. - """ - exp_data_list = self._exp_data_properties() - rb = qe.randomized_benchmarking - for exp_data in exp_data_list: - self.assertRaises( - QiskitError, - rb.RBExperiment, - exp_data["qubits"], - exp_data["lengths"], - num_samples=exp_data["num_samples"], - seed=exp_data["seed"], - )