def test_padding_less_than_sched_duration(self): """Test that the until arg is respected even for less than the input schedule duration.""" delay = 10 sched = (Delay(delay, DriveChannel(0)) + Delay(delay, DriveChannel(0)).shift(20)) ref_sched = (sched | pulse.Delay(5, DriveChannel(0)).shift(10)) self.assertEqual(transforms.pad(sched, until=15), ref_sched)
def test_transpile_and_sequence_agree_with_schedule_for_circuits_without_measures(self): qc = QuantumCircuit(2, name="bell_without_measurement") qc.h(0) qc.cx(0, 1) sc = transpile(qc, self.backend, scheduling_method="alap") actual = sequence(sc, self.backend) expected = schedule(transpile(qc, self.backend), self.backend) self.assertEqual(actual, pad(expected))
def test_padding_until_less(self): """Test padding until time that is less than schedule duration.""" delay = 10 sched = Delay(delay, DriveChannel(0)).shift(10) + Delay(delay, DriveChannel(1)) ref_sched = sched | Delay(delay, DriveChannel(0)) | Delay(5, DriveChannel(1)).shift(10) self.assertEqual(transforms.pad(sched, until=15), ref_sched)
def test_transpile_and_sequence_agree_with_schedule(self): qc = QuantumCircuit(2, name="bell") qc.h(0) qc.cx(0, 1) qc.measure_all() sc = transpile(qc, self.backend, scheduling_method='alap') actual = sequence(sc, self.backend) expected = schedule(transpile(qc, self.backend), self.backend) self.assertEqual(actual, pad(expected))
def test_padding_supplied_channels(self): """Test padding of only specified channels.""" delay = 10 sched = Delay(delay, DriveChannel(0)).shift(10) + Delay(delay, DriveChannel(1)) ref_sched = sched | Delay(delay, DriveChannel(0)) | Delay(2 * delay, DriveChannel(2)) channels = [DriveChannel(0), DriveChannel(2)] self.assertEqual(transforms.pad(sched, channels=channels), ref_sched)
def test_transpile_and_sequence_agree_with_schedule_for_circuit_with_delay( self): qc = QuantumCircuit(1, 1, name="t2") qc.h(0) qc.delay(500, 0, unit='ns') qc.h(0) qc.measure(0, 0) sc = transpile(qc, self.backend, scheduling_method='alap') actual = sequence(sc, self.backend) expected = schedule(qc.decompose(), self.backend) self.assertEqual(actual, pad(expected))
def test_padding_prepended_delay(self): """Test that there is delay before the first instruction.""" delay = 10 sched = (Delay(delay, DriveChannel(0)).shift(10) + Delay(delay, DriveChannel(0))) ref_sched = (Delay(delay, DriveChannel(0)) + Delay(delay, DriveChannel(0)) + Delay(delay, DriveChannel(0))) self.assertEqual(transforms.pad(sched, until=30, inplace=True), ref_sched)
def test_padding_until_greater(self): """Test padding until time that is greater than schedule duration.""" delay = 10 sched = (Delay(delay, DriveChannel(0)).shift(10) + Delay(delay, DriveChannel(1))) ref_sched = (sched | Delay(delay, DriveChannel(0)) | Delay(30, DriveChannel(0)).shift(20) | Delay(40, DriveChannel(1)).shift(10)) self.assertEqual(transforms.pad(sched, until=50), ref_sched)
def test_padding_schedule(self): """Test padding schedule.""" delay = 10 sched = (Delay(delay, DriveChannel(0)).shift(10) + Delay(delay, DriveChannel(0)).shift(10) + Delay(delay, DriveChannel(1)).shift(10)) ref_sched = (sched | Delay(delay, DriveChannel(0)) | Delay(delay, DriveChannel(0)).shift(20) | Delay(delay, DriveChannel(1)) | Delay(2 * delay, DriveChannel(1)).shift(20)) self.assertEqual(transforms.pad(sched), ref_sched)
def test_pad_no_delay_on_classical_io_channels(self): """Test padding does not apply to classical IO channels.""" delay = 10 sched = ( Delay(delay, MemorySlot(0)).shift(20) + Delay(delay, RegisterSlot(0)).shift(10) + Delay(delay, SnapshotChannel()) ) ref_sched = ( Delay(delay, MemorySlot(0)).shift(20) + Delay(delay, RegisterSlot(0)).shift(10) + Delay(delay, SnapshotChannel()) ) self.assertEqual(transforms.pad(sched, until=15), ref_sched)
def test_padding_schedule_inverse_order(self): """Test padding schedule is insensitive to order in which commands were added. This test is the same as `test_adding_schedule` but the order by channel in which commands were added to the schedule to be padded has been reversed. """ delay = 10 sched = (Delay(delay, DriveChannel(1)).shift(10) + Delay(delay, DriveChannel(0)).shift(10) + Delay(delay, DriveChannel(0)).shift(10)) ref_sched = (sched | Delay(delay, DriveChannel(0)) | Delay(delay, DriveChannel(0)).shift(20) | Delay(delay, DriveChannel(1)) | Delay(2 * delay, DriveChannel(1)).shift(20)) self.assertEqual(transforms.pad(sched), ref_sched)
def test_padding_empty_schedule(self): """Test padding of empty schedule.""" self.assertEqual(pulse.Schedule(), transforms.pad(pulse.Schedule()))
def sequence(scheduled_circuit: QuantumCircuit, schedule_config: ScheduleConfig) -> Schedule: """ Return the pulse Schedule which implements the input scheduled circuit. Assume all measurements are done at once at the last of the circuit. Schedules according to the command definition given by the schedule_config. Args: scheduled_circuit: The scheduled quantum circuit to translate. schedule_config: Backend specific parameters used for building the Schedule. Returns: A schedule corresponding to the input ``circuit``. Raises: QiskitError: If invalid scheduled circuit is supplied. """ circ_pulse_defs = lower_gates(scheduled_circuit, schedule_config) # find the measurement start time (assume measurement once) def _meas_start_time(): _qubit_time_available = defaultdict(int) for inst, qubits, _ in scheduled_circuit.data: if isinstance(inst, Measure): return _qubit_time_available[qubits[0]] for q in qubits: _qubit_time_available[q] += inst.duration return None meas_time = _meas_start_time() # restore start times qubit_time_available = {} start_times = [] out_circ_pulse_defs = [] for circ_pulse_def in circ_pulse_defs: active_qubits = [ q for q in circ_pulse_def.qubits if q in qubit_time_available ] start_time = max((qubit_time_available[q] for q in active_qubits), default=0) for q in active_qubits: if qubit_time_available[q] != start_time: # print(q, ":", qubit_time_available[q], "!=", start_time) raise QiskitError("Invalid scheduled circuit.") stop_time = start_time if not isinstance(circ_pulse_def.schedule, Barrier): stop_time += circ_pulse_def.schedule.duration delay_overlaps_meas = False for q in circ_pulse_def.qubits: qubit_time_available[q] = stop_time if (meas_time is not None and circ_pulse_def.schedule.name == "delay" and stop_time > meas_time): qubit_time_available[q] = meas_time delay_overlaps_meas = True # skip to delays overlapping measures and barriers if not delay_overlaps_meas and not isinstance(circ_pulse_def.schedule, Barrier): start_times.append(start_time) out_circ_pulse_defs.append(circ_pulse_def) timed_schedules = [(time, cpd.schedule) for time, cpd in zip(start_times, out_circ_pulse_defs)] sched = Schedule(*timed_schedules, name=scheduled_circuit.name) return pad(sched)