def test_update_from_instruction_schedule_map_update_schedule(self): self.pulse_target.dt = None inst_map = InstructionScheduleMap() with pulse.build(name="sx_q1") as custom_sx: pulse.play(pulse.Constant(1000, 0.2), pulse.DriveChannel(1)) inst_map.add("sx", 0, self.custom_sx_q0) inst_map.add("sx", 1, custom_sx) self.pulse_target.update_from_instruction_schedule_map(inst_map, {"sx": SXGate()}) self.assertEqual(inst_map, self.pulse_target.instruction_schedule_map()) self.assertIsNone(self.pulse_target["sx"][(0,)].duration) self.assertIsNone(self.pulse_target["sx"][(0,)].error) self.assertIsNone(self.pulse_target["sx"][(1,)].duration) self.assertIsNone(self.pulse_target["sx"][(1,)].error)
def test_frequency_offset(self): """Test the frequency offset context.""" d0 = pulse.DriveChannel(0) with pulse.build() as schedule: with pulse.frequency_offset(1e9, d0): pulse.delay(10, d0) reference = pulse.Schedule() reference += instructions.ShiftFrequency(1e9, d0) # pylint: disable=no-member reference += instructions.Delay(10, d0) reference += instructions.ShiftFrequency(-1e9, d0) # pylint: disable=no-member self.assertEqual(schedule, reference)
def test_default_schedule(self): """Test the default schedule.""" rabi = Rabi(2, self.sched) rabi.set_experiment_options(amplitudes=[0.5]) rabi.backend = RabiBackend() circs = rabi.circuits() with pulse.build() as expected: pulse.play(pulse.Gaussian(160, 0.5, 40), pulse.DriveChannel(2)) self.assertEqual(circs[0].calibrations["Rabi"][((2, ), (0.5, ))], expected) self.assertEqual(len(circs), 1)
def test_instruction_name_argument(self): """Test setting the name of an instruction.""" d0 = pulse.DriveChannel(0) for instruction_method in [ pulse.delay, pulse.set_frequency, pulse.set_phase, pulse.shift_frequency, pulse.shift_phase, ]: with pulse.build() as schedule: instruction_method(0, d0, name="instruction_name") self.assertEqual(schedule.instructions[0][1].name, "instruction_name")
def test_subroutine_not_transpiled(self): """Test called circuit is frozen as a subroutine.""" subprogram = circuit.QuantumCircuit(1) subprogram.x(0) transpiler_settings = {'optimization_level': 2} with pulse.build( self.backend, default_transpiler_settings=transpiler_settings) as schedule: pulse.call(subprogram) pulse.call(subprogram) self.assertNotEqual(len(inline_subroutines(schedule).instructions), 0)
def test_calibrations_no_params(self): """Check calibrations if the no params is provided with just gate name.""" circ = QuantumCircuit(3) with pulse.build() as q0_x180: pulse.play(pulse.library.Gaussian(20, 1.0, 3.0), pulse.DriveChannel(0)) circ.add_calibration("h", [0], q0_x180) self.assertEqual(set(circ.calibrations.keys()), {"h"}) self.assertEqual(set(circ.calibrations["h"].keys()), {((0, ), ())}) self.assertEqual(circ.calibrations["h"][((0, ), ())].instructions, q0_x180.instructions)
def test_inst_durations_from_calibrations(self): """Test that circuit calibrations can be used instead of explicitly supplying inst_durations. """ qc = QuantumCircuit(2) qc.append(Gate('custom', 1, []), [0]) with pulse.build() as cal: pulse.play(pulse.library.Gaussian(20, 1.0, 3.0), pulse.DriveChannel(0)) qc.add_calibration('custom', [0], cal) out = transpile(qc, scheduling_method='alap') self.assertEqual(out.duration, cal.duration)
def setUp(self): """Setup amplitude values.""" super().setUp() self.cals = Calibrations() self.qubit = 1 axp = Parameter("amp") chan = Parameter("ch0") with pulse.build(name="xp") as xp: pulse.play(pulse.Gaussian(duration=160, amp=axp, sigma=40), pulse.DriveChannel(chan)) ax90p = Parameter("amp") with pulse.build(name="x90p") as x90p: pulse.play(pulse.Gaussian(duration=160, amp=ax90p, sigma=40), pulse.DriveChannel(chan)) self.x90p = x90p self.cals.add_schedule(xp, num_qubits=1) self.cals.add_schedule(x90p, num_qubits=1) self.cals.add_parameter_value(0.2, "amp", self.qubit, "xp") self.cals.add_parameter_value(0.1, "amp", self.qubit, "x90p")
def _default_gate_schedule(self, backend: Optional[Backend] = None): """Create the default schedule for the Rabi gate.""" amp = Parameter("amp") with pulse.build(backend=backend, name="rabi") as default_schedule: pulse.play( pulse.Gaussian( duration=self.experiment_options.duration, amp=amp, sigma=self.experiment_options.sigma, ), pulse.DriveChannel(self.physical_qubits[0]), ) return default_schedule
def test_call(self): """Test calling schedule instruction.""" d0 = pulse.DriveChannel(0) d1 = pulse.DriveChannel(1) reference = pulse.Schedule() reference = reference.insert(10, instructions.Delay(10, d0)) reference += instructions.Delay(20, d1) ref_sched = pulse.Schedule() ref_sched += pulse.instructions.Call(reference) with pulse.build() as schedule: with pulse.align_right(): builder.call(reference) self.assertScheduleEqual(schedule, ref_sched) with pulse.build() as schedule: with pulse.align_right(): pulse.call(reference) self.assertScheduleEqual(schedule, ref_sched)
def test_calibrations_custom_gates(self): """Check if the calibrations for custom gates with params provided are added correctly.""" circ = QuantumCircuit(3) with pulse.build() as q0_x180: pulse.play(pulse.library.Gaussian(20, 1.0, 3.0), pulse.DriveChannel(0)) # Add calibrations with a custom gate 'rxt' circ.add_calibration('rxt', [0], q0_x180, params=[1.57, 3.14, 4.71]) self.assertEqual(set(circ.calibrations.keys()), {'rxt'}) self.assertEqual(set(circ.calibrations['rxt'].keys()), {((0,), (1.57, 3.14, 4.71))}) self.assertEqual(circ.calibrations['rxt'][((0,), (1.57, 3.14, 4.71))].instructions, q0_x180.instructions)
def test_call_partly_with_parameters(self): """Test multiple calls partly with parameters then assign.""" amp = circuit.Parameter('amp') with pulse.build() as subroutine: pulse.play(pulse.Gaussian(160, amp, 40), pulse.DriveChannel(0)) with pulse.build() as main_prog: pulse.call(subroutine, amp=0.1) pulse.call(subroutine) self.assertEqual(main_prog.is_parameterized(), True) main_prog.assign_parameters({amp: 0.5}) self.assertEqual(main_prog.is_parameterized(), False) assigned_sched = inline_subroutines(main_prog) play_0 = assigned_sched.instructions[0][1] play_1 = assigned_sched.instructions[1][1] self.assertEqual(play_0.pulse.amp, 0.1) self.assertEqual(play_1.pulse.amp, 0.5)
def setUp(self): """Setup the tests""" super().setUp() library = FixedFrequencyTransmon() self.backend = FakeArmonk() self.cals = Calibrations.from_backend(self.backend, library) # Add some pulses on the 1-2 transition. d0 = pulse.DriveChannel(0) with pulse.build(name="x12") as x12: with pulse.frequency_offset(-300e6, d0): pulse.play(pulse.Drag(160, Parameter("amp"), 40, 0.0), d0) with pulse.build(name="sx12") as sx12: with pulse.frequency_offset(-300e6, d0): pulse.play(pulse.Drag(160, Parameter("amp"), 40, 0.0), d0) self.cals.add_schedule(x12, 0) self.cals.add_schedule(sx12, 0) self.cals.add_parameter_value(0.4, "amp", 0, "x12") self.cals.add_parameter_value(0.2, "amp", 0, "sx12")
def test_update_from_instruction_schedule_map_with_error_dict(self): inst_map = InstructionScheduleMap() with pulse.build(name="sx_q1") as custom_sx: pulse.play(pulse.Constant(1000, 0.2), pulse.DriveChannel(1)) inst_map.add("sx", 0, self.custom_sx_q0) inst_map.add("sx", 1, custom_sx) self.pulse_target.dt = 1.0 error_dict = {"sx": {(1, ): 1.0}} self.pulse_target.update_from_instruction_schedule_map( inst_map, {"sx": SXGate()}, error_dict=error_dict) self.assertEqual(self.pulse_target["sx"][(1, )].error, 1.0) self.assertIsNone(self.pulse_target["sx"][(0, )].error)
def test_disassemble_parametric_pulses(self): """Test disassembling multiple schedules all should have the same config. """ d0 = pulse.DriveChannel(0) with pulse.build(self.backend) as sched: with pulse.align_right(): pulse.play(pulse.library.Constant(10, 1.0), d0) pulse.play(pulse.library.Gaussian(10, 1.0, 2.0), d0) pulse.play(pulse.library.GaussianSquare(10, 1.0, 2.0, 3), d0) pulse.play(pulse.library.Drag(10, 1.0, 2.0, 0.1), d0) qobj = assemble(sched, backend=self.backend, shots=2000) scheds, _, _ = disassemble(qobj) self.assertEqual(scheds[0], sched)
def test_phase_offset(self): """Test the phase offset context.""" d0 = pulse.DriveChannel(0) with pulse.build() as schedule: with pulse.phase_offset(3.14, d0): pulse.delay(10, d0) reference = pulse.Schedule() reference += instructions.ShiftPhase(3.14, d0) reference += instructions.Delay(10, d0) reference += instructions.ShiftPhase(-3.14, d0) self.assertEqual(schedule, reference)
def test_update_cals(self): """Test that the calibrations are updated.""" init_beta = 0.0 drag_cal = FineDragCal(0, self.cals, "x", self.backend) transpile_opts = copy.copy(drag_cal.transpile_options.__dict__) transpile_opts["initial_layout"] = list(drag_cal.physical_qubits) circs = transpile(drag_cal.circuits(), **transpile_opts) with pulse.build(name="x") as expected_x: pulse.play(pulse.Drag(160, 0.5, 40, 0), pulse.DriveChannel(0)) with pulse.build(name="sx") as expected_sx: pulse.play(pulse.Drag(160, 0.25, 40, 0), pulse.DriveChannel(0)) self.assertEqual(circs[5].calibrations["x"][((0,), ())], expected_x) self.assertEqual(circs[5].calibrations["sx"][((0,), ())], expected_sx) # run the calibration experiment. This should update the beta parameter of x which we test. exp_data = drag_cal.run(self.backend) d_theta = exp_data.analysis_results(1).value.value sigma = 40 target_angle = np.pi new_beta = -np.sqrt(np.pi) * d_theta * sigma / target_angle ** 2 transpile_opts = copy.copy(drag_cal.transpile_options.__dict__) transpile_opts["initial_layout"] = list(drag_cal.physical_qubits) circs = transpile(drag_cal.circuits(), **transpile_opts) x_cal = circs[5].calibrations["x"][((0,), ())] # Requires allclose due to numerical precision. self.assertTrue(np.allclose(x_cal.blocks[0].pulse.beta, new_beta)) self.assertFalse(np.allclose(x_cal.blocks[0].pulse.beta, init_beta)) self.assertEqual(circs[5].calibrations["sx"][((0,), ())], expected_sx)
def test_single_circuit_calibrations(self): """Test that disassembler parses single circuit QOBJ calibrations (from QOBJ-level).""" theta = Parameter("theta") qc = QuantumCircuit(2) qc.h(0) qc.rx(np.pi, 0) qc.rx(theta, 1) qc = qc.assign_parameters({theta: np.pi}) with pulse.build() as h_sched: pulse.play(pulse.library.Drag(1, 0.15, 4, 2), pulse.DriveChannel(0)) with pulse.build() as x180: pulse.play(pulse.library.Gaussian(1, 0.2, 5), pulse.DriveChannel(0)) qc.add_calibration("h", [0], h_sched) qc.add_calibration(RXGate(np.pi), [0], x180) qobj = assemble(qc, FakeOpenPulse2Q()) output_circuits, _, _ = disassemble(qobj) self.assertCircuitCalibrationsEqual([qc], output_circuits)
def test_qubit_channels(self): """Test getting the qubit channels of the active builder's backend.""" with pulse.build(self.backend): qubit_channels = pulse.qubit_channels(0) self.assertEqual( qubit_channels, { pulse.DriveChannel(0), pulse.MeasureChannel(0), pulse.AcquireChannel(0), pulse.ControlChannel(0), pulse.ControlChannel(1), }, )
def test_circuits(self): """Test the quantum circuits.""" test_amps = [-0.5, 0, 0.5] rabi = RoughXSXAmplitudeCal(0, self.cals, amplitudes=test_amps) circs = transpile(rabi.circuits(), self.backend, inst_map=rabi.transpile_options.inst_map) for circ, amp in zip(circs, test_amps): self.assertEqual(circ.count_ops()["Rabi"], 1) d0 = pulse.DriveChannel(0) with pulse.build(name="x") as expected_x: pulse.play(pulse.Drag(160, amp, 40, 0), d0) self.assertEqual(circ.calibrations["Rabi"][((0,), (amp,))], expected_x)
def test_ef_rabi_circuit(self): """Test the EFRabi experiment end to end.""" anharm = -330e6 rabi12 = EFRabi(2) rabi12.set_experiment_options(amplitudes=[0.5], frequency_shift=anharm) circ = rabi12.circuits(RabiBackend())[0] with pulse.build() as expected: pulse.shift_frequency(anharm, pulse.DriveChannel(2)) pulse.play(pulse.Gaussian(160, 0.5, 40), pulse.DriveChannel(2)) pulse.shift_frequency(-anharm, pulse.DriveChannel(2)) self.assertEqual(circ.calibrations["Rabi"][((2, ), (0.5, ))], expected) self.assertEqual(circ.data[0][0].name, "x") self.assertEqual(circ.data[1][0].name, "Rabi")
def setUp(self): """Setup for the test.""" super().setUp() self.inst_map = pulse.InstructionScheduleMap() self.sx_duration = 160 with pulse.build(name="sx") as sx_sched: pulse.play(pulse.Gaussian(self.sx_duration, 0.5, 40), pulse.DriveChannel(0)) self.inst_map.add("sx", 0, sx_sched) self.cals = Calibrations.from_backend(FakeArmonk(), FixedFrequencyTransmon())
def test_call_circuit_with_cregs(self): """Test calling of circuit wiht classical registers.""" qc = circuit.QuantumCircuit(2, 2) qc.h(0) qc.cx(0, 1) qc.measure([0, 1], [0, 1]) with pulse.build(self.backend) as schedule: pulse.call(qc) reference_qc = compiler.transpile(qc, self.backend) reference = compiler.schedule(reference_qc, self.backend) self.assertEqual(schedule, reference)
def test_calibrations_with_rzz_and_rxx(self): """Test calibrations annotations See https://github.com/Qiskit/qiskit-terra/issues/5920 """ circuit = QuantumCircuit(2, 2) circuit.rzz(pi, 0, 1) circuit.rxx(pi, 0, 1) from qiskit import pulse with pulse.build(name="rzz") as rzz_q01: pulse.play(pulse.library.Gaussian(duration=128, amp=0.1, sigma=16), pulse.DriveChannel(1)) circuit.add_calibration("rzz", [0, 1], rzz_q01) with pulse.build(name="rxx") as rxx_q01: pulse.play(pulse.library.Gaussian(duration=128, amp=0.1, sigma=16), pulse.DriveChannel(1)) circuit.add_calibration("rxx", [0, 1], rxx_q01) self.circuit_drawer(circuit, filename="calibrations_with_rzz_and_rxx.png")
def test_measure(self): """Test pulse measurement macro against circuit measurement and ensure agreement.""" with pulse.build(self.backend) as schedule: with pulse.align_sequential(): pulse.x(0) pulse.measure(0) reference_qc = circuit.QuantumCircuit(1, 1) reference_qc.x(0) reference_qc.measure(0, 0) reference_qc = compiler.transpile(reference_qc, self.backend) reference = compiler.schedule(reference_qc, self.backend) self.assertEqual(schedule, reference)
def test_barrier_on_qubits(self): """Test barrier directive on qubits.""" with pulse.build(self.backend) as schedule: pulse.barrier(0, 1) reference = pulse.Schedule() reference += directives.RelativeBarrier(pulse.DriveChannel(0), pulse.DriveChannel(1), pulse.MeasureChannel(0), pulse.MeasureChannel(1), pulse.ControlChannel(0), pulse.ControlChannel(1), pulse.AcquireChannel(0), pulse.AcquireChannel(1)) self.assertEqual(schedule, reference)
def test_phase_compensated_frequency_offset(self): """Test that the phase offset context properly compensates for phase accumulation.""" d0 = pulse.DriveChannel(0) with pulse.build(self.backend) as schedule: with pulse.frequency_offset(1e9, d0, compensate_phase=True): pulse.delay(10, d0) reference = pulse.Schedule() reference += instructions.ShiftFrequency(1e9, d0) # pylint: disable=no-member reference += instructions.Delay(10, d0) reference += instructions.ShiftPhase( -(1e9*10*self.configuration.dt % (2*np.pi)), d0) reference += instructions.ShiftFrequency(-1e9, d0) # pylint: disable=no-member self.assertEqual(schedule, reference)
def test_transpile_calibrated_custom_gate_on_diff_qubit(self): """Test if the custom, non calibrated gate raises QiskitError.""" custom_180 = Gate("mycustom", 1, [3.14]) circ = QuantumCircuit(2) circ.append(custom_180, [0]) with pulse.build() as q0_x180: pulse.play(pulse.library.Gaussian(20, 1.0, 3.0), pulse.DriveChannel(0)) # Add calibration circ.add_calibration(custom_180, [1], q0_x180) backend = FakeAlmaden() with self.assertRaises(QiskitError): transpile(circ, backend=backend)
def test_user_schedule(self): """Test the user given schedule.""" amp = Parameter("my_double_amp") with pulse.build() as my_schedule: pulse.play(pulse.Drag(160, amp, 40, 10), pulse.DriveChannel(2)) pulse.play(pulse.Drag(160, amp, 40, 10), pulse.DriveChannel(2)) rabi = Rabi(2) rabi.set_experiment_options(schedule=my_schedule, amplitudes=[0.5]) circs = rabi.circuits(RabiBackend()) assigned_sched = my_schedule.assign_parameters({amp: 0.5}, inplace=False) self.assertEqual(circs[0].calibrations["Rabi"][((2, ), (0.5, ))], assigned_sched)
def test_calibrations(self): """Test calibrations annotations See https://github.com/Qiskit/qiskit-terra/issues/5920 """ circuit = QuantumCircuit(2, 2) circuit.h(0) from qiskit import pulse with pulse.build(name="hadamard") as h_q0: pulse.play(pulse.library.Gaussian(duration=128, amp=0.1, sigma=16), pulse.DriveChannel(0)) circuit.add_calibration("h", [0], h_q0) self.circuit_drawer(circuit, filename="calibrations.png")