def test_complex_build(self): """Test a general program build with nested contexts, circuits and macros.""" d0 = pulse.DriveChannel(0) d1 = pulse.DriveChannel(1) d2 = pulse.DriveChannel(2) delay_dur = 19 short_dur = 31 long_dur = 101 with pulse.build(self.backend) as schedule: with pulse.align_sequential(): pulse.delay(delay_dur, d0) pulse.u2(0, pi / 2, 1) with pulse.align_right(): pulse.play(library.Constant(short_dur, 0.1), d1) pulse.play(library.Constant(long_dur, 0.1), d2) pulse.u2(0, pi / 2, 1) with pulse.align_left(): pulse.u2(0, pi / 2, 0) pulse.u2(0, pi / 2, 1) pulse.u2(0, pi / 2, 0) pulse.measure(0) # prepare and schedule circuits that will be used. single_u2_qc = circuit.QuantumCircuit(2) single_u2_qc.append(circuit.library.U2Gate(0, pi / 2), [1]) single_u2_qc = compiler.transpile(single_u2_qc, self.backend) single_u2_sched = compiler.schedule(single_u2_qc, self.backend) # sequential context sequential_reference = pulse.Schedule() sequential_reference += instructions.Delay(delay_dur, d0) sequential_reference.insert(delay_dur, single_u2_sched, inplace=True) # align right align_right_reference = pulse.Schedule() align_right_reference += pulse.Play(library.Constant(long_dur, 0.1), d2) align_right_reference.insert(long_dur - single_u2_sched.duration, single_u2_sched, inplace=True) align_right_reference.insert( long_dur - single_u2_sched.duration - short_dur, pulse.Play(library.Constant(short_dur, 0.1), d1), inplace=True) # align left triple_u2_qc = circuit.QuantumCircuit(2) triple_u2_qc.append(circuit.library.U2Gate(0, pi / 2), [0]) triple_u2_qc.append(circuit.library.U2Gate(0, pi / 2), [1]) triple_u2_qc.append(circuit.library.U2Gate(0, pi / 2), [0]) triple_u2_qc = compiler.transpile(triple_u2_qc, self.backend) align_left_reference = compiler.schedule(triple_u2_qc, self.backend, method='alap') # measurement measure_reference = macros.measure( qubits=[0], inst_map=self.inst_map, meas_map=self.configuration.meas_map) reference = pulse.Schedule() reference += sequential_reference # Insert so that the long pulse on d2 occurs as early as possible # without an overval on d1. insert_time = (reference.ch_stop_time(d1) - align_right_reference.ch_start_time(d1)) reference.insert(insert_time, align_right_reference, inplace=True) reference.insert(reference.ch_stop_time(d0, d1), align_left_reference, inplace=True) reference += measure_reference self.assertEqual(schedule, reference)
def test_drive_channel(self): """Text context builder drive channel.""" with pulse.build(self.backend): self.assertEqual(pulse.drive_channel(0), pulse.DriveChannel(0))
def test_trivial_barrier(self): """Test that trivial barrier is not added.""" with pulse.build() as schedule: pulse.barrier(pulse.DriveChannel(0)) self.assertEqual(schedule, pulse.Schedule())
def q0_rxt(tau): with pulse.build() as q0_rxt: pulse.play(pulse.library.Gaussian(20, 0.4 * tau, 3.0), pulse.DriveChannel(0)) return q0_rxt
def setUp(self): """Just some useful, reusable Parameters, constants, schedules.""" super().setUp() self.amp1_1 = Parameter('amp1_1') self.amp1_2 = Parameter('amp1_2') self.amp2 = Parameter('amp2') self.amp3 = Parameter('amp3') self.dur1 = Parameter('dur1') self.dur2 = Parameter('dur2') self.dur3 = Parameter('dur3') self.parametric_waveform1 = pulse.Gaussian(duration=self.dur1, amp=self.amp1_1 + self.amp1_2, sigma=self.dur1 / 4) self.parametric_waveform2 = pulse.Gaussian(duration=self.dur2, amp=self.amp2, sigma=self.dur2 / 5) self.parametric_waveform3 = pulse.Gaussian(duration=self.dur3, amp=self.amp3, sigma=self.dur3 / 6) self.ch1 = Parameter('ch1') self.ch2 = Parameter('ch2') self.ch3 = Parameter('ch3') self.d1 = pulse.DriveChannel(self.ch1) self.d2 = pulse.DriveChannel(self.ch2) self.d3 = pulse.DriveChannel(self.ch3) self.phi1 = Parameter('phi1') self.phi2 = Parameter('phi2') self.phi3 = Parameter('phi3') self.meas_dur = Parameter('meas_dur') self.mem1 = Parameter('s1') self.reg1 = Parameter('m1') self.context_dur = Parameter('context_dur') # schedule under test subroutine = pulse.ScheduleBlock(alignment_context=AlignLeft()) subroutine += pulse.ShiftPhase(self.phi1, self.d1) subroutine += pulse.Play(self.parametric_waveform1, self.d1) sched = pulse.Schedule() sched += pulse.ShiftPhase(self.phi3, self.d3) long_schedule = pulse.ScheduleBlock(alignment_context=AlignEquispaced( self.context_dur), name='long_schedule') long_schedule += subroutine long_schedule += pulse.ShiftPhase(self.phi2, self.d2) long_schedule += pulse.Play(self.parametric_waveform2, self.d2) long_schedule += pulse.Call(sched) long_schedule += pulse.Play(self.parametric_waveform3, self.d3) long_schedule += pulse.Acquire(self.meas_dur, pulse.AcquireChannel(self.ch1), mem_slot=pulse.MemorySlot(self.mem1), reg_slot=pulse.RegisterSlot(self.reg1)) self.test_sched = long_schedule
def test_circuit_generation_from_sec(self): """Test generated circuits when time unit is sec.""" backend = CrossResonanceHamiltonianBackend() expr = cr_hamiltonian.CrossResonanceHamiltonian( qubits=(0, 1), flat_top_widths=[500], unit="ns", amp=0.1, sigma=20, risefall=2, ) nearlest_16 = 576 with pulse.build(default_alignment="left", name="cr") as ref_cr_sched: pulse.play( pulse.GaussianSquare( nearlest_16, amp=0.1, sigma=20, width=500, ), pulse.ControlChannel(0), ) pulse.delay(nearlest_16, pulse.DriveChannel(0)) pulse.delay(nearlest_16, pulse.DriveChannel(1)) cr_gate = circuit.Gate("cr_gate", num_qubits=2, params=[500]) expr_circs = expr.circuits(backend) x0_circ = QuantumCircuit(2, 1) x0_circ.append(cr_gate, [0, 1]) x0_circ.h(1) x0_circ.measure(1, 0) x1_circ = QuantumCircuit(2, 1) x1_circ.x(0) x1_circ.append(cr_gate, [0, 1]) x1_circ.h(1) x1_circ.measure(1, 0) y0_circ = QuantumCircuit(2, 1) y0_circ.append(cr_gate, [0, 1]) y0_circ.sdg(1) y0_circ.h(1) y0_circ.measure(1, 0) y1_circ = QuantumCircuit(2, 1) y1_circ.x(0) y1_circ.append(cr_gate, [0, 1]) y1_circ.sdg(1) y1_circ.h(1) y1_circ.measure(1, 0) z0_circ = QuantumCircuit(2, 1) z0_circ.append(cr_gate, [0, 1]) z0_circ.measure(1, 0) z1_circ = QuantumCircuit(2, 1) z1_circ.x(0) z1_circ.append(cr_gate, [0, 1]) z1_circ.measure(1, 0) ref_circs = [x0_circ, y0_circ, z0_circ, x1_circ, y1_circ, z1_circ] for c in ref_circs: c.add_calibration(cr_gate, (0, 1), ref_cr_sched) self.assertListEqual(expr_circs, ref_circs)
name='pi_pulse') # Find out which group of qubits need to be acquired with this qubit meas_map_idx = None for i, measure_group in enumerate(backend_config.meas_map): if qubit in measure_group: meas_map_idx = i break assert meas_map_idx is not None, f"Couldn't find qubit {qubit} in the meas_map!" inst_sched_map = backend_defaults.instruction_schedule_map measure = inst_sched_map.get('measure', qubits=backend_config.meas_map[meas_map_idx]) ### Collect the necessary channels drive_chan = pulse.DriveChannel(qubit) meas_chan = pulse.MeasureChannel(qubit) acq_chan = pulse.AcquireChannel(qubit) # Create two schedules # Ground state schedule gnd_schedule = pulse.Schedule(name="ground state") gnd_schedule += measure # Excited state schedule exc_schedule = pulse.Schedule(name="excited state") exc_schedule += Play(pi_pulse, drive_chan) # We found this in Part 2A above exc_schedule += measure << exc_schedule.duration # Execution settings
def test_drag_roundtrip_serializable(self): """Test round trip JSON serialization""" with pulse.build(name="xp") as sched: pulse.play(pulse.Drag(160, 0.5, 40, Parameter("β")), pulse.DriveChannel(0)) exp = RoughDrag(0, backend=self.backend, schedule=sched) self.assertRoundTripSerializable(exp, self.json_equiv)
us = 1.0e-6 # Microseconds ns = 1.0e-9 # Nanoseconds qubit = 0 # qubit we will analyze default_qubit_freq = backend_defaults.qubit_freq_est[ qubit] # Default qubit frequency in Hz. #print(f"Qubit {qubit} has an estimated frequency of {default_qubit_freq/ GHz} GHz.") # scale data (specific to each device) scale_factor = 1e-14 # number of shots for our experiments NUM_SHOTS = 1024 ### Collect the necessary channels drive_chan = pulse.DriveChannel(qubit) meas_chan = pulse.MeasureChannel(qubit) acq_chan = pulse.AcquireChannel(qubit) # Drive pulse parameters (us = microseconds) drive_sigma_us = 0.075 # This determines the actual width of the gaussian drive_samples_us = drive_sigma_us * 8 # This is a truncating parameter, because gaussians don't have # a natural finite length drive_sigma = get_closest_multiple_of_16( drive_sigma_us * us / dt) # The width of the gaussian in units of dt drive_samples = get_closest_multiple_of_16(drive_samples_us * us / dt) # The truncating parameter in units of dt # Find out which measurement map index is needed for this qubit meas_map_idx = None for i, measure_group in enumerate(backend_config.meas_map): if qubit in measure_group:
def chart_channel_map(self, **kwargs): """Mock of chart channel mapper.""" names = ["D0", "D1"] chans = [[pulse.DriveChannel(0)], [pulse.DriveChannel(1)]] yield from zip(names, chans)
def test_circuit_generation(self): """Test generated circuits.""" backend = FakeBogota() # Add granularity to check duration optimization logic setattr( backend.configuration(), "timing_constraints", {"granularity": 16}, ) expr = cr_hamiltonian.CrossResonanceHamiltonian( qubits=(0, 1), flat_top_widths=[1000], amp=0.1, sigma=64, risefall=2, ) expr.backend = backend nearlest_16 = 1248 with pulse.build(default_alignment="left", name="cr") as ref_cr_sched: pulse.play( pulse.GaussianSquare( nearlest_16, amp=0.1, sigma=64, width=1000, ), pulse.ControlChannel(0), ) pulse.delay(nearlest_16, pulse.DriveChannel(0)) pulse.delay(nearlest_16, pulse.DriveChannel(1)) cr_gate = cr_hamiltonian.CrossResonanceHamiltonian.CRPulseGate( width=1000) expr_circs = expr.circuits() x0_circ = QuantumCircuit(2, 1) x0_circ.append(cr_gate, [0, 1]) x0_circ.h(1) x0_circ.measure(1, 0) x1_circ = QuantumCircuit(2, 1) x1_circ.x(0) x1_circ.append(cr_gate, [0, 1]) x1_circ.h(1) x1_circ.measure(1, 0) y0_circ = QuantumCircuit(2, 1) y0_circ.append(cr_gate, [0, 1]) y0_circ.sdg(1) y0_circ.h(1) y0_circ.measure(1, 0) y1_circ = QuantumCircuit(2, 1) y1_circ.x(0) y1_circ.append(cr_gate, [0, 1]) y1_circ.sdg(1) y1_circ.h(1) y1_circ.measure(1, 0) z0_circ = QuantumCircuit(2, 1) z0_circ.append(cr_gate, [0, 1]) z0_circ.measure(1, 0) z1_circ = QuantumCircuit(2, 1) z1_circ.x(0) z1_circ.append(cr_gate, [0, 1]) z1_circ.measure(1, 0) ref_circs = [x0_circ, y0_circ, z0_circ, x1_circ, y1_circ, z1_circ] for c in ref_circs: c.add_calibration(cr_gate, (0, 1), ref_cr_sched) self.assertListEqual(expr_circs, ref_circs)
"backend_name": "ibmq_armonk", "calibration_date": "5-11-2020", "drive_samples": 2688, "drive_sigma": 336, "pi_amp_01": 0.22109871419576962, "pi_amp_12": 0.36665303953291, "cal_qubit_freq": 4974529080.135406, "scale_factor": 1e-14, "qubit_12_freq": 4626195988.353748, "dt": 2.2222222222222221e-10 } pi_pulse_01 = get_pi_pulse_01(calibration) pi_pulse_12 = get_pi_pulse_12(calibration) drive_chan = pulse.DriveChannel(0) zero = pulse.Schedule(name="zero") zero |= measure_all(backend) one = pulse.Schedule(name="one") one |= pulse.Play(pi_pulse_01, drive_chan) one |= measure_all(backend) << one.duration two = pulse.Schedule(name="two") two |= pulse.Play(pi_pulse_01, drive_chan) two |= pulse.Play(pi_pulse_12, drive_chan) << two.duration two |= measure_all(backend) << two.duration prog = assemble_sched([zero, one, two], backend, calibration) job = backend.run(prog)
def setUp(self) -> None: super().setUp() self.channels = [ pulse.DriveChannel(0), pulse.DriveChannel(1), pulse.DriveChannel(2), pulse.MeasureChannel(1), pulse.MeasureChannel(2), pulse.AcquireChannel(1), pulse.AcquireChannel(2), pulse.ControlChannel(0), pulse.ControlChannel(2), pulse.ControlChannel(5), ] self.formatter = {"control.show_acquire_channel": True} self.device = device_info.OpenPulseBackendInfo( name="test", dt=1, channel_frequency_map={ pulse.DriveChannel(0): 5.0e9, pulse.DriveChannel(1): 5.1e9, pulse.DriveChannel(2): 5.2e9, pulse.MeasureChannel(1): 7.0e9, pulse.MeasureChannel(1): 7.1e9, pulse.MeasureChannel(2): 7.2e9, pulse.ControlChannel(0): 5.0e9, pulse.ControlChannel(1): 5.1e9, pulse.ControlChannel(2): 5.2e9, pulse.ControlChannel(3): 5.3e9, pulse.ControlChannel(4): 5.4e9, pulse.ControlChannel(5): 5.5e9, }, qubit_channel_map={ 0: [ pulse.DriveChannel(0), pulse.MeasureChannel(0), pulse.AcquireChannel(0), pulse.ControlChannel(0), ], 1: [ pulse.DriveChannel(1), pulse.MeasureChannel(1), pulse.AcquireChannel(1), pulse.ControlChannel(1), ], 2: [ pulse.DriveChannel(2), pulse.MeasureChannel(2), pulse.AcquireChannel(2), pulse.ControlChannel(2), pulse.ControlChannel(3), pulse.ControlChannel(4), ], 3: [ pulse.DriveChannel(3), pulse.MeasureChannel(3), pulse.AcquireChannel(3), pulse.ControlChannel(5), ], }, )
def circuits(self, backend: Optional[Backend] = None) -> List[QuantumCircuit]: """Create the circuits for the Drag calibration. Args: backend: A backend object. Returns: circuits: The circuits that will run the Drag calibration. Raises: CalibrationError: - If the beta parameters in the xp and xm pulses are not the same. - If either the xp or xm pulse do not have at least one Drag pulse. - If the number of different repetition series is not three. """ schedule = self.experiment_options.schedule if schedule is None: beta = Parameter("β") with pulse.build(backend=backend, name="drag") as schedule: pulse.play( pulse.Drag( duration=self.experiment_options.duration, amp=self.experiment_options.amp, sigma=self.experiment_options.sigma, beta=beta, ), pulse.DriveChannel(self._physical_qubits[0]), ) if len(schedule.parameters) != 1: raise CalibrationError( "The schedule for Drag calibration must have one free parameter." f"Found {len(schedule.parameters)}.") beta = next(iter(schedule.parameters)) drag_gate = Gate(name=schedule.name, num_qubits=1, params=[beta]) reps = self.experiment_options.reps if len(reps) != 3: raise CalibrationError( f"{self.__class__.__name__} must use exactly three repetition numbers. " f"Received {reps} with length {len(reps)} != 3.") circuits = [] for idx, rep in enumerate(reps): circuit = QuantumCircuit(1) for _ in range(rep): circuit.append(drag_gate, (0, )) circuit.rz(np.pi, 0) circuit.append(drag_gate, (0, )) circuit.rz(np.pi, 0) circuit.measure_active() circuit.add_calibration(schedule.name, self.physical_qubits, schedule, params=[beta]) for beta_val in self.experiment_options.betas: beta_val = np.round(beta_val, decimals=6) assigned_circuit = circuit.assign_parameters({beta: beta_val}, inplace=False) assigned_circuit.metadata = { "experiment_type": self._type, "qubits": self.physical_qubits, "xval": beta_val, "series": idx, } circuits.append(assigned_circuit) return circuits