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_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_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)
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"])
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"])
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)
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")
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")
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_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())
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)
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))
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)
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))
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)
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)
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
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_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))
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)
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")
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)
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")
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)