Exemplo n.º 1
0
    def test_parallel_options(self):
        """
        Test parallel experiments overriding sub-experiment run and transpile options.
        """
        # These options will all be overridden
        exp0 = FakeExperiment([0])
        exp0.set_transpile_options(optimization_level=1)
        exp2 = FakeExperiment([2])
        exp2.set_experiment_options(dummyoption="test")
        exp2.set_run_options(shots=2000)
        exp2.set_transpile_options(optimization_level=1)
        exp2.analysis.set_options(dummyoption="test")

        par_exp = ParallelExperiment([exp0, exp2])

        self.assertEqual(par_exp.experiment_options,
                         par_exp._default_experiment_options())
        self.assertEqual(par_exp.run_options, Options(meas_level=2))
        self.assertEqual(par_exp.transpile_options,
                         Options(optimization_level=0))
        self.assertEqual(par_exp.analysis.options,
                         par_exp.analysis._default_options())

        with self.assertWarns(UserWarning):
            expdata = par_exp.run(FakeBackend())
        self.assertExperimentDone(expdata)
Exemplo n.º 2
0
    def test_calibrations(self):
        """Test that the calibrations are preserved and that the circuit transpiles."""

        experiments = []
        for qubit in range(3):
            rabi = Rabi(qubit)
            rabi.set_experiment_options(amplitudes=[0.5])
            experiments.append(rabi)

        par_exp = ParallelExperiment(experiments)
        par_circ = par_exp.circuits()[0]

        # If the calibrations are not there we will not be able to transpile
        try:
            transpile(par_circ, basis_gates=["rz", "sx", "x", "cx"])
        except QiskitError as error:
            self.fail("Failed to transpile with error: " + str(error))

        # Assert that the calibration keys are in the calibrations of the composite circuit.
        for qubit in range(3):
            rabi_circuit = experiments[qubit].circuits()[0]
            cal_key = next(iter(rabi_circuit.calibrations["Rabi"].keys()))

            self.assertEqual(cal_key[0], (qubit, ))
            self.assertTrue(cal_key in par_circ.calibrations["Rabi"])
Exemplo n.º 3
0
    def test_calibrations(self):
        """Test that the calibrations are preserved and that the circuit transpiles."""

        experiments = []
        for qubit in range(3):
            with pulse.build() as sched:
                pulse.play(pulse.Gaussian(160, Parameter("amp"), 40),
                           pulse.DriveChannel(qubit))

            experiments.append(Rabi(qubit, sched, amplitudes=[0.5]))

        par_exp = ParallelExperiment(experiments)
        par_circ = par_exp.circuits()[0]

        # If the calibrations are not there we will not be able to transpile
        try:
            transpile(par_circ, basis_gates=["rz", "sx", "x", "cx"])
        except QiskitError as error:
            self.fail("Failed to transpile with error: " + str(error))

        # Assert that the calibration keys are in the calibrations of the composite circuit.
        for qubit in range(3):
            rabi_circuit = experiments[qubit].circuits()[0]
            cal_key = next(iter(rabi_circuit.calibrations["Rabi"].keys()))

            self.assertEqual(cal_key[0], (qubit, ))
            self.assertTrue(cal_key in par_circ.calibrations["Rabi"])
Exemplo n.º 4
0
    def test_t1_parallel_different_analysis_options(self):
        """
        Test parallel experiments of T1 using a simulator, for the case where
        the sub-experiments have different analysis options
        """

        t1 = 25
        delays = list(range(1, 40, 3))

        exp0 = T1(0, delays)
        exp0.set_analysis_options(t1_guess=30)
        exp1 = T1(1, delays)
        exp1.set_analysis_options(t1_guess=1000000)

        par_exp = ParallelExperiment([exp0, exp1])
        res = par_exp.run(T1Backend([t1, t1]))
        res.block_for_results()

        sub_res = []
        for i in range(2):
            sub_res.append(
                res.component_experiment_data(i).analysis_results(0))

        self.assertEqual(sub_res[0].quality, "good")
        self.assertAlmostEqual(sub_res[0].value.value, t1, delta=3)
        self.assertEqual(sub_res[1].quality, "bad")
Exemplo n.º 5
0
    def test_t1_parallel_different_analysis_options(self):
        """
        Test parallel experiments of T1 using a simulator, for the case where
        the sub-experiments have different analysis options
        """

        t1 = 25
        delays = list(range(1, 40, 3))

        exp0 = T1(0, delays)
        exp0.analysis.set_options(p0={"tau": 30})
        exp1 = T1(1, delays)
        exp1.analysis.set_options(p0={"tau": 1000000})

        par_exp = ParallelExperiment([exp0, exp1])
        res = par_exp.run(T1Backend([t1, t1]))
        self.assertExperimentDone(res)

        sub_res = []
        for i in range(2):
            sub_res.append(res.child_data(i).analysis_results("T1"))

        self.assertEqual(sub_res[0].quality, "good")
        self.assertAlmostEqual(sub_res[0].value.n, t1, delta=3)
        self.assertEqual(sub_res[1].quality, "bad")
Exemplo n.º 6
0
    def test_composite_copy_analysis_ref(self):
        """Test copy of composite expeirment preserves component analysis refs"""

        class Analysis(FakeAnalysis):
            """Fake analysis class with options"""

            @classmethod
            def _default_options(cls):
                opts = super()._default_options()
                opts.option1 = None
                opts.option2 = None
                return opts

        exp1 = FakeExperiment([0])
        exp1.analysis = Analysis()
        exp2 = FakeExperiment([1])
        exp2.analysis = Analysis()

        # Generate a copy
        par_exp = ParallelExperiment([exp1, exp2]).copy()
        comp_exp0 = par_exp.component_experiment(0)
        comp_exp1 = par_exp.component_experiment(1)
        comp_an0 = par_exp.analysis.component_analysis(0)
        comp_an1 = par_exp.analysis.component_analysis(1)

        # Check reference of analysis is preserved
        self.assertTrue(comp_exp0.analysis is comp_an0)
        self.assertTrue(comp_exp1.analysis is comp_an1)
Exemplo n.º 7
0
    def test_parallel_options(self):
        """
        Test parallel experiments overriding sub-experiment run and transpile options.
        """
        # These options will all be overridden
        exp0 = FakeExperiment([0])
        exp0.set_transpile_options(optimization_level=1)
        exp2 = FakeExperiment([2])
        exp2.set_experiment_options(dummyoption="test")
        exp2.set_run_options(shots=2000)
        exp2.set_transpile_options(optimization_level=1)
        exp2.analysis.set_options(dummyoption="test")

        par_exp = ParallelExperiment([exp0, exp2])

        with self.assertWarnsRegex(
                Warning,
                "Sub-experiment run and transpile options"
                " are overridden by composite experiment options.",
        ):
            self.assertEqual(par_exp.experiment_options, Options())
            self.assertEqual(par_exp.run_options, Options(meas_level=2))
            self.assertEqual(par_exp.transpile_options,
                             Options(optimization_level=0))
            self.assertEqual(par_exp.analysis.options, Options())

            par_exp.run(FakeBackend())
Exemplo n.º 8
0
    def test_t1_parallel(self):
        """
        Test parallel experiments of T1 using a simulator.
        """

        t1 = [25, 15]
        delays = list(range(1, 40, 3))

        exp0 = T1(0, delays)
        exp2 = T1(2, delays)
        par_exp = ParallelExperiment([exp0, exp2])
        res = par_exp.run(T1Backend([t1[0], None, t1[1]]))
        self.assertExperimentDone(res)

        for i in range(2):
            sub_res = res.child_data(i).analysis_results("T1")
            self.assertEqual(sub_res.quality, "good")
            self.assertAlmostEqual(sub_res.value.n, t1[i], delta=3)

        res.service = FakeService()
        res.save()
        loaded_data = ExperimentData.load(res.experiment_id, res.service)

        for i in range(2):
            sub_res = res.child_data(i).analysis_results("T1")
            sub_loaded = loaded_data.child_data(i).analysis_results("T1")
            self.assertEqual(repr(sub_res), repr(sub_loaded))
Exemplo n.º 9
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)
Exemplo n.º 10
0
 def test_parallel_running(self):
     """Test that parallel experiments work for this experiment"""
     backend = AerSimulator.from_backend(FakeParis())
     exp1 = CorrelatedReadoutError([0, 2])
     exp2 = CorrelatedReadoutError([1, 3])
     exp = ParallelExperiment([exp1, exp2])
     expdata = exp.run(backend=backend).block_for_results()
     mit1 = expdata.child_data(0).analysis_results(0).value
     mit2 = expdata.child_data(1).analysis_results(0).value
     assignment_matrix1 = mit1.assignment_matrix()
     assignment_matrix2 = mit2.assignment_matrix()
     self.assertFalse(matrix_equal(assignment_matrix1, assignment_matrix2))
Exemplo n.º 11
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")
Exemplo n.º 12
0
    def test_t2hahn_parallel(self):
        """
        Test parallel experiments of T2Hahn using a simulator.
        """
        t2hahn = [30, 25]
        delays = [list(range(1, 60)), list(range(1, 50))]
        osc_freq = [0.11, 0.11]

        exp0 = T2Hahn(0, delays[0])
        exp2 = T2Hahn(2, delays[1])

        exp0.analysis.set_options(p0={
            "amp": 0.5,
            "tau": t2hahn[0],
            "base": 0.5
        },
                                  plot=True)
        exp2.analysis.set_options(p0={
            "amp": 0.5,
            "tau": t2hahn[1],
            "base": 0.5
        },
                                  plot=True)

        par_exp = ParallelExperiment([exp0, exp2])

        p0 = {
            "A": [0.5, None, 0.5],
            "T2": [t2hahn[0], None, t2hahn[1]],
            "frequency": [osc_freq[0], None, osc_freq[1]],
            "B": [0.5, None, 0.5],
        }

        backend = T2HahnBackend(
            t2hahn=p0["T2"],
            frequency=p0["frequency"],
            initialization_error=[0.0],
            readout0to1=[0.02],
            readout1to0=[0.02],
        )
        expdata = par_exp.run(backend=backend, shots=1024).block_for_results()

        for i in range(2):
            res_t2 = expdata.child_data(i).analysis_results("T2")

            fitval = res_t2.value
            self.assertEqual(res_t2.quality, "good")
            self.assertAlmostEqual(fitval.n, t2hahn[i], delta=3)
Exemplo n.º 13
0
    def test_composite_analysis_options(self):
        """Test setting component analysis options"""

        class Analysis(FakeAnalysis):
            """Fake analysis class with options"""

            @classmethod
            def _default_options(cls):
                opts = super()._default_options()
                opts.option1 = None
                opts.option2 = None
                return opts

        exp1 = FakeExperiment([0])
        exp1.analysis = Analysis()
        exp2 = FakeExperiment([1])
        exp2.analysis = Analysis()
        par_exp = ParallelExperiment([exp1, exp2])

        # Set new analysis classes to component exp objects
        opt1_val = 9000
        opt2_val = 2113
        exp1.analysis.set_options(option1=opt1_val)
        exp2.analysis.set_options(option2=opt2_val)

        # Check this is reflected in parallel experiment
        self.assertEqual(par_exp.analysis.component_analysis(0).options.option1, opt1_val)
        self.assertEqual(par_exp.analysis.component_analysis(1).options.option2, opt2_val)
Exemplo n.º 14
0
    def test_t2ramsey_parallel(self):
        """
        Test parallel experiments of T2Ramsey using a simulator.
        """
        t2ramsey = [30, 25]
        estimated_freq = [0.1, 0.12]
        delays = [list(range(1, 60)), list(range(1, 50))]

        osc_freq = [0.11, 0.11]

        exp0 = T2Ramsey(0, delays[0], osc_freq=osc_freq[0])
        exp2 = T2Ramsey(2, delays[1], osc_freq=osc_freq[1])
        par_exp = ParallelExperiment([exp0, exp2])

        p0 = {
            "A": [0.5, None, 0.5],
            "T2star": [t2ramsey[0], None, t2ramsey[1]],
            "f": [estimated_freq[0], None, estimated_freq[1]],
            "phi": [0, None, 0],
            "B": [0.5, None, 0.5],
        }

        backend = T2RamseyBackend(p0)
        expdata = par_exp.run(backend=backend, shots=1000)
        self.assertExperimentDone(expdata)

        for i in range(2):
            res_t2star = expdata.child_data(i).analysis_results("T2star")
            self.assertAlmostEqual(
                res_t2star.value.n,
                t2ramsey[i],
                delta=TestT2Ramsey.__tolerance__ * res_t2star.value.n,
            )
            self.assertEqual(
                res_t2star.quality, "good",
                "Result quality bad for experiment on qubit " + str(i))
            res_freq = expdata.child_data(i).analysis_results("Frequency")
            self.assertAlmostEqual(
                res_freq.value.n,
                estimated_freq[i],
                delta=TestT2Ramsey.__tolerance__ * res_freq.value.n,
            )
            self.assertEqual(
                res_freq.quality, "good",
                "Result quality bad for experiment on qubit " + str(i))
Exemplo n.º 15
0
    def test_t1_parallel(self):
        """
        Test parallel experiments of T1 using a simulator.
        """

        t1 = [25, 15]
        delays = list(range(1, 40, 3))

        exp0 = T1(0, delays)
        exp2 = T1(2, delays)
        par_exp = ParallelExperiment([exp0, exp2])
        res = par_exp.run(T1Backend([t1[0], None, t1[1]]))
        res.block_for_results()

        for i in range(2):
            sub_res = res.component_experiment_data(i).analysis_results(0)
            self.assertEqual(sub_res.quality, "good")
            self.assertAlmostEqual(sub_res.value.value, t1[i], delta=3)
Exemplo n.º 16
0
    def test_parallel_exp(self):
        """Test parallel process tomography experiment"""
        # Subsystem unitaries
        seed = 1221
        nq = 4
        ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)]

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

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

        # Check target fidelity of component experiments
        f_threshold = 0.95
        for i in range(par_exp.num_experiments):
            results = par_data.child_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")
Exemplo n.º 17
0
 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)
Exemplo n.º 18
0
    def test_analysis_replace_results_true(self):
        """
        Test replace results when analyzing composite experiment data
        """
        exp1 = FakeExperiment([0, 2])
        exp2 = FakeExperiment([1, 3])
        par_exp = ParallelExperiment([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,
                                     replace_results=True).block_for_results()
        self.assertEqual(data1, data2)
        self.assertEqual(len(data1.child_data()), len(data2.child_data()))
        for sub1, sub2 in zip(data1.child_data(), data2.child_data()):
            self.assertEqual(sub1, sub2)
Exemplo n.º 19
0
    def test_t1_parallel_exp_transpile(self):
        """Test parallel transpile options for T1 experiment"""
        num_qubits = 5
        instruction_durations = []
        for i in range(num_qubits):
            instruction_durations += [
                ("rx", [i], (i + 1) * 10, "ns"),
                ("measure", [i], (i + 1) * 1000, "ns"),
            ]
        coupling_map = [[i - 1, i] for i in range(1, num_qubits)]
        basis_gates = ["rx", "delay"]

        exp1 = T1(1, delays=[50e-9, 100e-9, 160e-9])
        exp2 = T1(3, delays=[40e-9, 80e-9, 190e-9])
        parexp = ParallelExperiment([exp1, exp2])
        parexp.set_transpile_options(
            basis_gates=basis_gates,
            instruction_durations=instruction_durations,
            coupling_map=coupling_map,
            scheduling_method="alap",
        )

        circs = parexp.circuits()
        for circ in circs:
            self.assertEqual(circ.num_qubits, 2)
            op_counts = circ.count_ops()
            self.assertEqual(op_counts.get("rx"), 2)
            self.assertEqual(op_counts.get("delay"), 2)

        tcircs = parexp._transpiled_circuits()
        for circ in tcircs:
            self.assertEqual(circ.num_qubits, num_qubits)
            op_counts = circ.count_ops()
            self.assertEqual(op_counts.get("rx"), 2)
            self.assertGreater(op_counts.get("delay"), num_qubits - 1)
    def test_parallel_exp(self):
        """Test parallel state tomography experiment"""
        # Subsystem unitaries
        seed = 1221
        nq = 4
        ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)]

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

        # Run batch experiments
        backend = AerSimulator(seed_simulator=9000)
        par_exp = ParallelExperiment(exps)
        par_data = par_exp.run(backend)
        par_data.block_for_results()

        # Check target fidelity of component experiments
        f_threshold = 0.95
        for i in range(par_exp.num_experiments):
            results = par_data.component_experiment_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")
Exemplo n.º 21
0
    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)
Exemplo n.º 22
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
Exemplo n.º 23
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
Exemplo n.º 24
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)