From 3ae1c85e31798cfe64db7d05ca47aab7ee98bfb0 Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Sun, 7 Nov 2021 18:06:30 +0200 Subject: [PATCH 1/5] test marginalization --- test/test_composite.py | 148 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/test/test_composite.py b/test/test_composite.py index 5226d8b078..6c0faba02a 100644 --- a/test/test_composite.py +++ b/test/test_composite.py @@ -15,10 +15,13 @@ from typing import Optional, List, Dict, Type, Any, Union, Tuple import json import copy +import uuid from test.fake_backend import FakeBackend from test.fake_experiment import FakeExperiment +from qiskit.circuit import QuantumCircuit +from qiskit.result import Result from qiskit.test import QiskitTestCase from qiskit.test.mock import FakeMelbourne @@ -30,6 +33,7 @@ ) from qiskit_experiments.database_service import DatabaseServiceV1 from qiskit_experiments.database_service.device_component import DeviceComponent +from qiskit_experiments.test.utils import FakeJob # pylint: disable=missing-raises-doc @@ -261,7 +265,7 @@ def preferences(self) -> Dict: class TestCompositeExperimentData(QiskitTestCase): """ - Test operations on objects of composit ExperimentData + Test operations on objects of composite ExperimentData """ def setUp(self): @@ -400,3 +404,145 @@ def test_analysis_replace_results_false(self): self.assertEqual(len(data1.child_data()), len(data2.child_data())) for sub1, sub2 in zip(data1.child_data(), data2.child_data()): self.assertNotEqual(sub1.experiment_id, sub2.experiment_id) + + def test_parallel_subexp_data(self): + """ + Verify that sub-experiment data of a parallel experiment is + correctly marginalized + """ + + class Backend(FakeBackend): + def run(self, run_input, **options): + counts = [ + { + "0000": 1, + "0010": 6, + "0011": 3, + "0100": 4, + "0101": 2, + "0110": 1, + "0111": 3, + "1000": 5, + "1001": 3, + "1010": 4, + "1100": 4, + "1101": 3, + "1110": 8, + "1111": 5, + }, + { + "0001": 3, + "0010": 4, + "0011": 5, + "0100": 2, + "0101": 1, + "0111": 7, + "1000": 3, + "1001": 2, + "1010": 1, + "1011": 1, + "1100": 7, + "1101": 8, + "1110": 2, + }, + { + "0000": 1, + "0001": 1, + "0010": 8, + "0011": 7, + "0100": 2, + "0101": 2, + "0110": 2, + "0111": 1, + "1000": 6, + "1010": 4, + "1011": 4, + "1100": 5, + "1101": 2, + "1110": 2, + "1111": 5, + }, + { + "0000": 4, + "0001": 5, + "0101": 4, + "0110": 8, + "0111": 2, + "1001": 6, + "1010": 8, + "1011": 8, + "1101": 1, + "1110": 3, + "1111": 3, + }, + { + "0000": 3, + "0001": 6, + "0010": 7, + "0011": 1, + "0100": 1, + "0101": 5, + "0110": 4, + "1000": 2, + "1001": 4, + "1011": 3, + "1100": 6, + "1111": 1, + }, + ] + + results = [] + for circ, cnt in zip(run_input, counts): + results.append( + { + "shots": -1, + "success": True, + "header": {"metadata": circ.metadata}, + "data": {"counts": cnt}, + } + ) + + res = { + "backend_name": "backend", + "backend_version": "0", + "qobj_id": uuid.uuid4().hex, + "job_id": uuid.uuid4().hex, + "success": True, + "results": results, + } + return FakeJob(backend=self, result=Result.from_dict(res)) + + class Experiment(FakeExperiment): + def circuits(self): + circs = [] + for i in range(5): + circ = QuantumCircuit(2, 2) + circ.metadata = {} + circs.append(circ) + return circs + + exp1 = Experiment([0, 2]) + exp2 = Experiment([1, 3]) + par_exp = ParallelExperiment([exp1, exp2]) + expdata = par_exp.run(Backend()).block_for_results() + + expected_counts = [ + [ + {"00": 14, "10": 19, "11": 11, "01": 8}, + {"01": 14, "10": 7, "11": 13, "00": 12}, + {"00": 14, "01": 5, "10": 16, "11": 17}, + {"00": 4, "01": 16, "10": 19, "11": 13}, + {"00": 12, "01": 15, "10": 11, "11": 5}, + ], + [ + {"00": 10, "01": 10, "10": 12, "11": 20}, + {"00": 12, "01": 10, "10": 7, "11": 17}, + {"00": 17, "01": 7, "10": 14, "11": 14}, + {"00": 9, "01": 14, "10": 22, "11": 7}, + {"00": 17, "01": 10, "10": 9, "11": 7}, + ], + ] + + for child, counts in zip(expdata.child_data(), expected_counts): + for child_counts, cnt in zip(child.data(), counts): + self.assertDictEqual(child_counts["counts"], cnt) From 32b9ae2e3eb5c8decfd6c3733a048a6bf11a90b2 Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Mon, 8 Nov 2021 09:00:47 +0200 Subject: [PATCH 2/5] test parallel batch and nested --- test/test_composite.py | 221 ++++++++++++++++++++++++----------------- 1 file changed, 131 insertions(+), 90 deletions(-) diff --git a/test/test_composite.py b/test/test_composite.py index 6c0faba02a..a6f4c7e834 100644 --- a/test/test_composite.py +++ b/test/test_composite.py @@ -405,92 +405,94 @@ def test_analysis_replace_results_false(self): for sub1, sub2 in zip(data1.child_data(), data2.child_data()): self.assertNotEqual(sub1.experiment_id, sub2.experiment_id) - def test_parallel_subexp_data(self): + def test_composite_subexp_data(self): """ - Verify that sub-experiment data of a parallel experiment is - correctly marginalized + Verify that sub-experiment data of parallel and batch + experiments are correctly marginalized """ + counts = [ + { + "0000": 1, + "0010": 6, + "0011": 3, + "0100": 4, + "0101": 2, + "0110": 1, + "0111": 3, + "1000": 5, + "1001": 3, + "1010": 4, + "1100": 4, + "1101": 3, + "1110": 8, + "1111": 5, + }, + { + "0001": 3, + "0010": 4, + "0011": 5, + "0100": 2, + "0101": 1, + "0111": 7, + "1000": 3, + "1001": 2, + "1010": 1, + "1011": 1, + "1100": 7, + "1101": 8, + "1110": 2, + }, + { + "0000": 1, + "0001": 1, + "0010": 8, + "0011": 7, + "0100": 2, + "0101": 2, + "0110": 2, + "0111": 1, + "1000": 6, + "1010": 4, + "1011": 4, + "1100": 5, + "1101": 2, + "1110": 2, + "1111": 5, + }, + { + "0000": 4, + "0001": 5, + "0101": 4, + "0110": 8, + "0111": 2, + "1001": 6, + "1010": 8, + "1011": 8, + "1101": 1, + "1110": 3, + "1111": 3, + }, + { + "0000": 3, + "0001": 6, + "0010": 7, + "0011": 1, + "0100": 1, + "0101": 5, + "0110": 4, + "1000": 2, + "1001": 4, + "1011": 3, + "1100": 6, + "1111": 1, + }, + ] class Backend(FakeBackend): + """ + Bacekend to be used in test_composite_subexp_data + """ def run(self, run_input, **options): - counts = [ - { - "0000": 1, - "0010": 6, - "0011": 3, - "0100": 4, - "0101": 2, - "0110": 1, - "0111": 3, - "1000": 5, - "1001": 3, - "1010": 4, - "1100": 4, - "1101": 3, - "1110": 8, - "1111": 5, - }, - { - "0001": 3, - "0010": 4, - "0011": 5, - "0100": 2, - "0101": 1, - "0111": 7, - "1000": 3, - "1001": 2, - "1010": 1, - "1011": 1, - "1100": 7, - "1101": 8, - "1110": 2, - }, - { - "0000": 1, - "0001": 1, - "0010": 8, - "0011": 7, - "0100": 2, - "0101": 2, - "0110": 2, - "0111": 1, - "1000": 6, - "1010": 4, - "1011": 4, - "1100": 5, - "1101": 2, - "1110": 2, - "1111": 5, - }, - { - "0000": 4, - "0001": 5, - "0101": 4, - "0110": 8, - "0111": 2, - "1001": 6, - "1010": 8, - "1011": 8, - "1101": 1, - "1110": 3, - "1111": 3, - }, - { - "0000": 3, - "0001": 6, - "0010": 7, - "0011": 1, - "0100": 1, - "0101": 5, - "0110": 4, - "1000": 2, - "1001": 4, - "1011": 3, - "1100": 6, - "1111": 1, - }, - ] - results = [] for circ, cnt in zip(run_input, counts): results.append( @@ -513,20 +515,35 @@ def run(self, run_input, **options): return FakeJob(backend=self, result=Result.from_dict(res)) class Experiment(FakeExperiment): + """ + Experiment to be used in test_composite_subexp_data + """ + def __init__(self, qubits, num_circs): + super().__init__(qubits) + self._ncircs = num_circs + def circuits(self): + nqubits = len(self._physical_qubits) circs = [] - for i in range(5): - circ = QuantumCircuit(2, 2) + for _ in range(self._ncircs): + circ = QuantumCircuit(nqubits, nqubits) circ.metadata = {} circs.append(circ) return circs - exp1 = Experiment([0, 2]) - exp2 = Experiment([1, 3]) - par_exp = ParallelExperiment([exp1, exp2]) + exp1 = Experiment([0, 2], 5) + exp2 = Experiment([1], 2) + exp3 = Experiment([3], 2) + exp4 = Experiment([1, 3], 3) + par_exp = ParallelExperiment( + [exp1, BatchExperiment([ParallelExperiment([exp2, exp3]), exp4])] + ) expdata = par_exp.run(Backend()).block_for_results() - expected_counts = [ + for circ_data, circ_counts in zip(expdata.data(), counts): + self.assertDictEqual(circ_data["counts"], circ_counts) + + counts1 = [ [ {"00": 14, "10": 19, "11": 11, "01": 8}, {"01": 14, "10": 7, "11": 13, "00": 12}, @@ -543,6 +560,30 @@ def circuits(self): ], ] - for child, counts in zip(expdata.child_data(), expected_counts): - for child_counts, cnt in zip(child.data(), counts): - self.assertDictEqual(child_counts["counts"], cnt) + for childdata, child_counts in zip(expdata.child_data(), counts1): + for circ_data, circ_counts in zip(childdata.data(), child_counts): + self.assertDictEqual(circ_data["counts"], circ_counts) + + counts2 = [ + [{"00": 10, "01": 10, "10": 12, "11": 20}, {"00": 12, "01": 10, "10": 7, "11": 17}], + [ + {"00": 17, "01": 7, "10": 14, "11": 14}, + {"00": 9, "01": 14, "10": 22, "11": 7}, + {"00": 17, "01": 10, "10": 9, "11": 7}, + ], + ] + + for childdata, child_counts in zip(expdata.child_data(1).child_data(), counts2): + for circ_data, circ_counts in zip(childdata.data(), child_counts): + self.assertDictEqual(circ_data["counts"], circ_counts) + + counts3 = [ + [{"0": 22, "1": 31}, {"0": 19, "1": 27}], + [{"0": 20, "1": 32}, {"0": 22, "1": 24}], + ] + + for childdata, child_counts in zip( + expdata.child_data(1).child_data(0).child_data(), counts3 + ): + for circ_data, circ_counts in zip(childdata.data(), child_counts): + self.assertDictEqual(circ_data["counts"], circ_counts) From 75d16ae4ac90eb8d41fe9a332dd1c7235013c113 Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Mon, 8 Nov 2021 09:26:37 +0200 Subject: [PATCH 3/5] black --- test/test_composite.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test_composite.py b/test/test_composite.py index a6f4c7e834..f7c73719c6 100644 --- a/test/test_composite.py +++ b/test/test_composite.py @@ -492,6 +492,7 @@ class Backend(FakeBackend): """ Bacekend to be used in test_composite_subexp_data """ + def run(self, run_input, **options): results = [] for circ, cnt in zip(run_input, counts): @@ -518,6 +519,7 @@ class Experiment(FakeExperiment): """ Experiment to be used in test_composite_subexp_data """ + def __init__(self, qubits, num_circs): super().__init__(qubits) self._ncircs = num_circs From 61cfbb1c715b3f6a4de84d57edca38f450d2b5e4 Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Tue, 16 Nov 2021 15:21:19 +0200 Subject: [PATCH 4/5] fixed test --- test/test_composite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_composite.py b/test/test_composite.py index 879d6a4b73..cb645b06a8 100644 --- a/test/test_composite.py +++ b/test/test_composite.py @@ -580,7 +580,7 @@ def circuits(self): self.assertDictEqual(circ_data["counts"], circ_counts) counts3 = [ - [{"0": 22, "1": 31}, {"0": 19, "1": 27}], + [{"0": 22, "1": 30}, {"0": 19, "1": 27}], [{"0": 20, "1": 32}, {"0": 22, "1": 24}], ] From b2c729a86a0eae61bcdf5fac1e5d7a25eeee2466 Mon Sep 17 00:00:00 2001 From: Yael Ben-Haim Date: Wed, 17 Nov 2021 08:42:19 +0200 Subject: [PATCH 5/5] fixed conflict resolve --- test/test_composite.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/test_composite.py b/test/test_composite.py index 5b0c7c5ff8..832fdb081d 100644 --- a/test/test_composite.py +++ b/test/test_composite.py @@ -20,6 +20,10 @@ from test.fake_service import FakeService from test.base import QiskitExperimentsTestCase +from qiskit import QuantumCircuit +from qiskit.result import Result + +from qiskit_experiments.test.utils import FakeJob from qiskit_experiments.framework import ( ParallelExperiment, Options,