Example #1
0
    def test_composite_tags(self):
        """
        Test the tags setter, add_tags_recursive, remove_tags_recursive
        """
        exp1 = FakeExperiment([0, 2])
        exp2 = FakeExperiment([1, 3])
        par_exp = BatchExperiment([exp1, exp2])
        expdata = par_exp.run(FakeBackend()).block_for_results()
        data1 = expdata.child_data(0)
        data2 = expdata.child_data(1)

        expdata.tags = ["a", "c", "a"]
        data1.tags = ["b"]
        self.assertEqual(sorted(expdata.tags), ["a", "c"])
        self.assertEqual(sorted(data1.tags), ["b"])
        self.assertEqual(sorted(data2.tags), [])

        expdata.add_tags_recursive(["d", "c"])
        self.assertEqual(sorted(expdata.tags), ["a", "c", "d"])
        self.assertEqual(sorted(data1.tags), ["b", "c", "d"])
        self.assertEqual(sorted(data2.tags), ["c", "d"])

        expdata.remove_tags_recursive(["a", "b"])
        self.assertEqual(sorted(expdata.tags), ["c", "d"])
        self.assertEqual(sorted(data1.tags), ["c", "d"])
        self.assertEqual(sorted(data2.tags), ["c", "d"])
    def setUp(self):
        super().setUp()

        exp1 = self.SimpleExperiment(range(4))
        exp2 = self.SimpleExperiment(range(4))
        exp3 = self.SimpleExperiment(range(4))
        batch1 = BatchExperiment([exp2, exp3])
        self.batch2 = BatchExperiment([exp1, batch1])

        exp1.set_transpile_options(coupling_map=[[0, 1], [1, 3], [3, 2]])
        exp2.set_transpile_options(coupling_map=[[0, 1], [1, 2], [2, 3]])
Example #3
0
    def test_experiment_config(self):
        """Test converting to and from config works"""
        exp1 = FakeExperiment([0])
        exp1.set_run_options(shots=1000)
        exp2 = FakeExperiment([2])
        exp2.set_run_options(shots=2000)

        exp = BatchExperiment([exp1, exp2])

        loaded_exp = BatchExperiment.from_config(exp.config())
        self.assertNotEqual(exp, loaded_exp)
        self.assertTrue(self.json_equiv(exp, loaded_exp))
Example #4
0
 def test_nested_composite(self):
     """
     Test nested parallel experiments.
     """
     exp1 = FakeExperiment([0, 2])
     exp2 = FakeExperiment([1, 3])
     exp3 = ParallelExperiment([exp1, exp2])
     exp4 = BatchExperiment([exp3, exp1])
     exp5 = ParallelExperiment([exp4, FakeExperiment([4])])
     nested_exp = BatchExperiment([exp5, exp3])
     expdata = nested_exp.run(FakeBackend())
     self.assertExperimentDone(expdata)
    def test_mixed_batch_exp(self):
        """Test batch state and process tomography experiment"""
        # Subsystem unitaries
        state_op = qi.random_unitary(2, seed=321)
        chan_op = qi.random_unitary(2, seed=123)

        state_target = qi.Statevector(state_op.to_instruction())
        chan_target = qi.Choi(chan_op.to_instruction())

        state_exp = StateTomography(state_op)
        chan_exp = ProcessTomography(chan_op)
        batch_exp = BatchExperiment([state_exp, chan_exp])

        # Run batch experiments
        backend = AerSimulator(seed_simulator=9000)
        par_data = batch_exp.run(backend)
        self.assertExperimentDone(par_data)

        f_threshold = 0.95

        # Check state tomo results
        state_results = par_data.child_data(0).analysis_results()
        state = filter_results(state_results, "state").value

        # Check fit state fidelity
        state_fid = filter_results(state_results, "state_fidelity").value
        self.assertGreater(state_fid, f_threshold, msg="fit fidelity is low")

        # Manually check fidelity
        target_fid = qi.state_fidelity(state, state_target, validate=False)
        self.assertAlmostEqual(state_fid,
                               target_fid,
                               places=6,
                               msg="result fidelity is incorrect")

        # Check process tomo results
        chan_results = par_data.child_data(1).analysis_results()
        chan = filter_results(chan_results, "state").value

        # Check fit process fidelity
        chan_fid = filter_results(chan_results, "process_fidelity").value
        self.assertGreater(chan_fid, f_threshold, msg="fit fidelity is low")

        # Manually check fidelity
        target_fid = qi.process_fidelity(chan,
                                         chan_target,
                                         require_cp=False,
                                         require_tp=False)
        self.assertAlmostEqual(chan_fid,
                               target_fid,
                               places=6,
                               msg="result fidelity is incorrect")
Example #6
0
 def test_nested_composite(self):
     """
     Test nested parallel experiments.
     """
     exp1 = FakeExperiment([0, 2])
     exp2 = FakeExperiment([1, 3])
     exp3 = ParallelExperiment([exp1, exp2])
     exp4 = BatchExperiment([exp3, exp1])
     exp5 = ParallelExperiment([exp4, FakeExperiment([4])])
     nested_exp = BatchExperiment([exp5, exp3])
     expdata = nested_exp.run(FakeBackend()).block_for_results()
     status = expdata.status()
     self.assertEqual(status.name, "DONE")
    def test_batch_exp_with_measurement_qubits(self):
        """Test batch process tomography experiment with kwargs"""
        seed = 1111
        nq = 3
        ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)]

        # Preparation circuit
        circuit = QuantumCircuit(nq)
        for i, op in enumerate(ops):
            circuit.append(op, [i])

        # Component experiments
        exps = []
        targets = []
        for i in range(nq):
            targets.append(ops[i])
            exps.append(
                ProcessTomography(circuit,
                                  measurement_qubits=[i],
                                  preparation_qubits=[i]))

        # Run batch experiments
        backend = AerSimulator(seed_simulator=9000)
        batch_exp = BatchExperiment(exps)
        batch_data = batch_exp.run(backend)
        batch_data.block_for_results()

        # Check target fidelity of component experiments
        f_threshold = 0.95
        for i in range(batch_exp.num_experiments):
            results = batch_data.component_experiment_data(
                i).analysis_results()

            # Check state is density matrix
            state = filter_results(results, "state").value
            self.assertTrue(isinstance(state, qi.Choi),
                            msg="fitted state is not a Choi matrix")

            # Check fit state fidelity
            fid = filter_results(results, "process_fidelity").value
            self.assertGreater(fid, f_threshold, msg="fit fidelity is low")

            # Manually check fidelity
            target_fid = qi.process_fidelity(state,
                                             targets[i],
                                             require_tp=False,
                                             require_cp=False)
            self.assertAlmostEqual(fid,
                                   target_fid,
                                   places=6,
                                   msg="result fidelity is incorrect")
Example #8
0
    def setUp(self):
        super().setUp()

        self.backend = FakeBackend()
        self.share_level = "hey"

        exp1 = FakeExperiment([0, 2])
        exp2 = FakeExperiment([1, 3])
        par_exp = ParallelExperiment([exp1, exp2])
        exp3 = FakeExperiment([0, 1, 2, 3])
        batch_exp = BatchExperiment([par_exp, exp3])

        self.rootdata = batch_exp.run(backend=self.backend).block_for_results()
        self.assertEqual(len(self.rootdata.child_data()), 2)

        self.rootdata.share_level = self.share_level
    def test_batch_exp(self):
        """Test batch state tomography experiment with measurement_qubits kwarg"""
        # Subsystem unitaries
        seed = 1111
        nq = 3
        ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)]

        # Preparation circuit
        circuit = QuantumCircuit(nq)
        for i, op in enumerate(ops):
            circuit.append(op, [i])

        # Component experiments
        exps = []
        targets = []
        for i in range(nq):
            targets.append(qi.Statevector(ops[i].to_instruction()))
            exps.append(StateTomography(circuit, measurement_qubits=[i]))

        # Run batch experiments
        backend = AerSimulator(seed_simulator=9000)
        batch_exp = BatchExperiment(exps)
        batch_data = batch_exp.run(backend)
        self.assertExperimentDone(batch_data)

        # Check target fidelity of component experiments
        f_threshold = 0.95
        for i in range(batch_exp.num_experiments):
            results = batch_data.child_data(i).analysis_results()

            # Check state is density matrix
            state = filter_results(results, "state").value
            self.assertTrue(isinstance(state, qi.DensityMatrix),
                            msg="fitted state is not density matrix")

            # Check fit state fidelity
            fid = filter_results(results, "state_fidelity").value
            self.assertGreater(fid, f_threshold, msg="fit fidelity is low")

            # Manually check fidelity
            target_fid = qi.state_fidelity(state, targets[i], validate=False)
            self.assertAlmostEqual(fid,
                                   target_fid,
                                   places=6,
                                   msg="result fidelity is incorrect")
Example #10
0
    def test_roundtrip_serializable(self):
        """Test round trip JSON serialization"""
        exp1 = FakeExperiment([0])
        exp1.set_run_options(shots=1000)
        exp2 = FakeExperiment([2])
        exp2.set_run_options(shots=2000)

        exp = BatchExperiment([exp1, exp2])

        self.assertRoundTripSerializable(exp, self.json_equiv)
 def test_flatten_results_nested(self):
     """Test combining results."""
     exp0 = FakeExperiment([0])
     exp1 = FakeExperiment([1])
     exp2 = FakeExperiment([2])
     exp3 = FakeExperiment([3])
     comp_exp = ParallelExperiment(
         [
             BatchExperiment(2 * [ParallelExperiment([exp0, exp1])]),
             BatchExperiment(3 * [ParallelExperiment([exp2, exp3])]),
         ],
         flatten_results=True,
     )
     expdata = comp_exp.run(FakeBackend())
     self.assertExperimentDone(expdata)
     # Check no child data was saved
     self.assertEqual(len(expdata.child_data()), 0)
     # Check right number of analysis results is returned
     self.assertEqual(len(expdata.analysis_results()), 30)
Example #12
0
    def test_analysis_replace_results_false(self):
        """
        Test replace_results of composite experiment data
        """
        exp1 = FakeExperiment([0, 2])
        exp2 = FakeExperiment([1, 3])
        par_exp = BatchExperiment([exp1, exp2])
        data1 = par_exp.run(FakeBackend()).block_for_results()

        # Additional data not part of composite experiment
        exp3 = FakeExperiment([0, 1])
        extra_data = exp3.run(FakeBackend()).block_for_results()
        data1.add_child_data(extra_data)

        # Replace results
        data2 = par_exp.analysis.run(data1).block_for_results()
        self.assertNotEqual(data1.experiment_id, data2.experiment_id)
        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_flatten_results_partial(self):
        """Test flattening results."""
        exp0 = FakeExperiment([0])
        exp1 = FakeExperiment([1])
        exp2 = FakeExperiment([2])
        exp3 = FakeExperiment([3])
        comp_exp = BatchExperiment([
            ParallelExperiment([exp0, exp1, exp2], flatten_results=True),
            ParallelExperiment([exp2, exp3], flatten_results=True),
        ], )
        expdata = comp_exp.run(FakeBackend())
        self.assertExperimentDone(expdata)
        # Check out experiment wasnt flattened
        self.assertEqual(len(expdata.child_data()), 2)
        self.assertEqual(len(expdata.analysis_results()), 0)

        # check inner experiments were flattened
        child0 = expdata.child_data(0)
        child1 = expdata.child_data(1)
        self.assertEqual(len(child0.child_data()), 0)
        self.assertEqual(len(child1.child_data()), 0)
        # Check right number of analysis results is returned
        self.assertEqual(len(child0.analysis_results()), 9)
        self.assertEqual(len(child1.analysis_results()), 6)
Example #14
0
    def setUp(self):
        super().setUp()

        self.backend = FakeMelbourne()
        self.share_level = "hey"

        exp1 = FakeExperiment([0, 2])
        exp2 = FakeExperiment([1, 3])
        par_exp = ParallelExperiment([exp1, exp2])
        exp3 = FakeExperiment(4)
        batch_exp = BatchExperiment([par_exp, exp3])

        self.rootdata = CompositeExperimentData(batch_exp,
                                                backend=self.backend)

        self.rootdata.share_level = self.share_level
Example #15
0
    def test_composite_subexp_data(self):
        """
        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):
                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):
            """
            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 _ in range(self._ncircs):
                    circ = QuantumCircuit(nqubits, nqubits)
                    circ.metadata = {}
                    circs.append(circ)
                return circs

        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()

        self.assertEqual(len(expdata.data()), len(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
                },
                {
                    "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
                },
            ],
        ]

        self.assertEqual(len(expdata.child_data()), len(counts1))
        for childdata, child_counts in zip(expdata.child_data(), counts1):
            self.assertEqual(len(childdata.data()), len(child_counts))
            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
                },
            ],
        ]

        self.assertEqual(len(expdata.child_data(1).child_data()), len(counts2))
        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": 30
            }, {
                "0": 19,
                "1": 27
            }],
            [{
                "0": 20,
                "1": 32
            }, {
                "0": 22,
                "1": 24
            }],
        ]

        self.assertEqual(len(expdata.child_data(1).child_data(0).child_data()),
                         len(counts3))
        for childdata, child_counts in zip(
                expdata.child_data(1).child_data(0).child_data(), counts3):
            self.assertEqual(len(childdata.data()), len(child_counts))
            for circ_data, circ_counts in zip(childdata.data(), child_counts):
                self.assertDictEqual(circ_data["counts"], circ_counts)
class TestBatchTranspileOptions(QiskitExperimentsTestCase):
    """
    For batch experiments, circuits are transpiled with the transpile options of the
    sub-experiments
    """
    class SimpleExperiment(BaseExperiment):
        """
        An experiment that creates a circuit of four qubits.
        Qubits 1 and 2 are inactive.
        Qubits 0 and 3 form a Bell state.
        The purpose: we will test with varying coupling maps, spanning from a coupling map that
        directly connects qubits 0 and 3 (hence qubits 1 and 2 remains inactive also in the
        transpiled circuit) to a coupling map with distance 3 between qubits 0 and 3.
        """
        def __init__(self, qubits, backend=None):
            super().__init__(
                qubits,
                analysis=TestBatchTranspileOptions.SimpleAnalysis(),
                backend=backend)

        def circuits(self):
            circ = QuantumCircuit(4, 4)
            circ.h(0)
            circ.cx(0, 3)
            circ.barrier()
            circ.measure(range(4), range(4))
            return [circ]

    class SimpleAnalysis(BaseAnalysis):
        """
        The number of non-zero counts is equal to
        2^(distance between qubits 0 and 3 in the transpiled circuit + 1)
        """
        def _run_analysis(self, experiment_data):
            analysis_results = [
                AnalysisResultData(name="non-zero counts",
                                   value=len(
                                       experiment_data.data(0)["counts"])),
            ]

            return analysis_results, []

    def setUp(self):
        super().setUp()

        exp1 = self.SimpleExperiment(range(4))
        exp2 = self.SimpleExperiment(range(4))
        exp3 = self.SimpleExperiment(range(4))
        batch1 = BatchExperiment([exp2, exp3])
        self.batch2 = BatchExperiment([exp1, batch1])

        exp1.set_transpile_options(coupling_map=[[0, 1], [1, 3], [3, 2]])
        exp2.set_transpile_options(coupling_map=[[0, 1], [1, 2], [2, 3]])

        # exp3 circuit: two active qubits and six instructions: hadamard, cnot, four measurements.
        # exp1 circuit: three active qubits (0, 1, 3) and seven instructions: hadamard,
        #               two 2Q gates, four measurements.
        # exp2 circuit: four active qubits and eight instructions.

    def test_batch_transpiled_circuits(self):
        """
        For batch experiments, circuits are transpiled with the transpile options of the
        sub-experiments
        """
        circs = self.batch2._transpiled_circuits()
        numbers_of_gates = [len(circ.data) for circ in circs]
        self.assertEqual(set(numbers_of_gates), set([7, 8, 9]))

    def test_batch_transpile_options_integrated(self):
        """
        The goal is to verify that not only `_trasnpiled_circuits` works well
        (`test_batch_transpiled_circuits` takes care of it) but that it's correctly called within
        the entire flow of `BaseExperiment.run`.
        """
        backend = Aer.get_backend("aer_simulator")
        noise_model = noise.NoiseModel()
        noise_model.add_all_qubit_quantum_error(
            noise.depolarizing_error(0.5, 2), ["cx", "swap"])

        expdata = self.batch2.run(backend, noise_model=noise_model, shots=1000)
        expdata.block_for_results()

        self.assertEqual(expdata.child_data(0).analysis_results(0).value, 8)
        self.assertEqual(
            expdata.child_data(1).child_data(0).analysis_results(0).value, 16)
        self.assertEqual(
            expdata.child_data(1).child_data(1).analysis_results(0).value, 4)