Exemplo n.º 1
0
 def test_fail_measure(self):
     """Test failing measure."""
     with self.assertRaises(PulseError):
         macros.measure(qubits=[0],
                        meas_map=self.backend.configuration().meas_map)
     with self.assertRaises(PulseError):
         macros.measure(qubits=[0], inst_map=self.inst_map)
Exemplo n.º 2
0
 def test_measure_sched_with_meas_map(self):
     """Test measure with custom meas_map as list and dict."""
     sched_with_meas_map_list = macros.measure(qubits=[0],
                                               backend=self.backend,
                                               meas_map=[[0, 1]])
     sched_with_meas_map_dict = macros.measure(qubits=[0],
                                               backend=self.backend,
                                               meas_map={0: [0, 1], 1: [0, 1]})
     expected = Schedule(
         self.inst_map.get('measure', [0, 1]).filter(channels=[MeasureChannel(0)]),
         Acquire(10, AcquireChannel(0), MemorySlot(0)),
         Acquire(10, AcquireChannel(1), MemorySlot(1)))
     self.assertEqual(sched_with_meas_map_list.instructions, expected.instructions)
     self.assertEqual(sched_with_meas_map_dict.instructions, expected.instructions)
Exemplo n.º 3
0
    def test_call_gate_and_circuit(self):
        """Test calling circuit with gates."""
        h_control = circuit.QuantumCircuit(2)
        h_control.h(0)

        with pulse.build(self.backend) as schedule:
            with pulse.align_sequential():
                # this is circuit, a subroutine stored as Call instruction
                pulse.call(h_control)
                # this is instruction, not subroutine
                pulse.cx(0, 1)
                # this is macro, not subroutine
                pulse.measure([0, 1])

        # subroutine
        h_reference = compiler.schedule(compiler.transpile(h_control, self.backend), self.backend)

        # gate
        cx_circ = circuit.QuantumCircuit(2)
        cx_circ.cx(0, 1)
        cx_reference = compiler.schedule(compiler.transpile(cx_circ, self.backend), self.backend)

        # measurement
        measure_reference = macros.measure(
            qubits=[0, 1], inst_map=self.inst_map, meas_map=self.configuration.meas_map
        )

        reference = pulse.Schedule()
        reference += pulse.instructions.Call(h_reference)
        reference += cx_reference
        reference += measure_reference << reference.duration

        self.assertScheduleEqual(schedule, reference)
Exemplo n.º 4
0
def rabi_schedules(amp_list, qubits, pulse_width, pulse_sigma=None,
                   width_sigma_ratio=4, drives=None,
                   inst_map=None, meas_map=None):
    """
    Generates schedules for a rabi experiment using a Gaussian pulse

    Args:
        amp_list (list): A list of floats of amplitudes for the Gaussian
            pulse [-1,1]
        qubits (list): A list of integers for indices of the qubits to perform
            a rabi
        pulse_width (float): width of gaussian (in dt units)
        pulse_sigma (float): sigma of gaussian
        width_sigma_ratio (int): set sigma to a certain ratio of the width
            (use if pulse_sigma is None)
        drives (list): list of :class:`~qiskit.pulse.DriveChannel` objects
        inst_map (qiskit.pulse.InstructionScheduleMap): InstructionScheduleMap
            object to use
        meas_map (list): meas_map to use

    Returns:
       A list of QuantumSchedules
       xdata: a list of amps

    Raises:
        QiskitError: when necessary variables are not supplied.
    """
    xdata = amp_list

    # copy the instruction to schedule mapping
    inst_map = copy.deepcopy(inst_map)

    # Following variables should not be optional.
    # To keep function interface constant, errors are inserted here.
    # TODO: redesign this function in next release
    if inst_map is None:
        QiskitError('Instruction schedule map is not provided. ',
                    'Run `backend.defaults().instruction_schedule_map` to get inst_map.')
    if meas_map is None:
        QiskitError('Measurement map is not provided. ',
                    'Run `backend.configuration().meas_map` to get meas_map.')

    if pulse_sigma is None:
        pulse_sigma = pulse_width / width_sigma_ratio

    # Construct the schedules
    rabi_scheds = []
    for index, g_amp in enumerate(amp_list):
        rabi_pulse = pulse_lib.gaussian(duration=pulse_width,
                                        amp=g_amp,
                                        sigma=pulse_sigma,
                                        name='rabi_pulse_%d' % index)
        sched = pulse.Schedule(name='rabisched_%d_0' % index)
        for qubit in qubits:
            sched += pulse.Play(rabi_pulse, drives[qubit])
        sched += measure(qubits, inst_map=inst_map, meas_map=meas_map).shift(pulse_width)
        rabi_scheds.append(sched)

    return rabi_scheds, xdata
Exemplo n.º 5
0
    def test_measure_with_custom_inst_map(self):
        """Test measure with custom inst_map, meas_map with measure_name."""
        q0_sched = Play(GaussianSquare(1200, 1, 0.4, 1150), MeasureChannel(0))
        q0_sched += Acquire(1200, AcquireChannel(0), MemorySlot(0))
        inst_map = InstructionScheduleMap()
        inst_map.add('my_sched', 0, q0_sched)
        sched = macros.measure(qubits=[0],
                               measure_name='my_sched',
                               inst_map=inst_map,
                               meas_map=[[0]])
        self.assertEqual(sched.instructions, q0_sched.instructions)

        with self.assertRaises(PulseError):
            macros.measure(qubits=[0],
                           measure_name="name",
                           inst_map=inst_map,
                           meas_map=[[0]])
Exemplo n.º 6
0
 def test_measure(self):
     """Test macro - measure."""
     sched = macros.measure(qubits=[0], backend=self.backend)
     expected = Schedule(
         self.inst_map.get('measure',
                           [0, 1]).filter(channels=[MeasureChannel(0)]),
         Acquire(10, AcquireChannel(0), MemorySlot(0)),
         Acquire(10, AcquireChannel(1), MemorySlot(1)))
     self.assertEqual(sched.instructions, expected.instructions)
Exemplo n.º 7
0
 def test_measure_sched_with_qubit_mem_slots(self):
     """Test measure with custom qubit_mem_slots."""
     sched = macros.measure(qubits=[0],
                            backend=self.backend,
                            qubit_mem_slots={0: 1})
     expected = Schedule(
         self.inst_map.get('measure', [0, 1]).filter(channels=[MeasureChannel(0)]),
         Acquire(10, AcquireChannel(0), MemorySlot(1)),
         Acquire(10, AcquireChannel(1), MemorySlot(0)))
     self.assertEqual(sched.instructions, expected.instructions)
Exemplo n.º 8
0
    def test_measure(self):
        """Test utility function - measure."""
        with pulse.build(self.backend) as schedule:
            reg = pulse.measure(0)

        self.assertEqual(reg, pulse.MemorySlot(0))

        reference = macros.measure(qubits=[0],
                                   inst_map=self.inst_map,
                                   meas_map=self.configuration.meas_map)

        self.assertEqual(schedule, reference)
Exemplo n.º 9
0
    def test_measure_multi_qubits(self):
        """Test utility function - measure with multi qubits."""
        with pulse.build(self.backend) as schedule:
            regs = pulse.measure([0, 1])

        self.assertListEqual(regs, [pulse.MemorySlot(0), pulse.MemorySlot(1)])

        reference = macros.measure(qubits=[0, 1],
                                   inst_map=self.inst_map,
                                   meas_map=self.configuration.meas_map)

        self.assertEqual(schedule, reference)
Exemplo n.º 10
0
 def get_measure_schedule() -> CircuitPulseDef:
     """Create a schedule to measure the qubits queued for measuring."""
     sched = Schedule()
     sched += measure(qubits=list(qubit_mem_slots.keys()),
                      inst_map=inst_map,
                      meas_map=schedule_config.meas_map,
                      qubit_mem_slots=qubit_mem_slots)
     qubit_mem_slots.clear()
     return CircuitPulseDef(schedule=sched,
                            qubits=[
                                chan.index for chan in sched.channels
                                if isinstance(chan, AcquireChannel)
                            ])
Exemplo n.º 11
0
    def get_measure_schedule(
            qubit_mem_slots: Dict[int, int]) -> CircuitPulseDef:
        """Create a schedule to measure the qubits queued for measuring."""
        sched = Schedule()
        # Exclude acquisition on these qubits, since they are handled by the user calibrations
        acquire_excludes = {}
        if Measure().name in circuit.calibrations.keys():
            qubits = tuple(sorted(qubit_mem_slots.keys()))
            params = ()
            for qubit in qubits:
                try:
                    meas_q = circuit.calibrations[Measure().name][((qubit, ),
                                                                   params)]
                    meas_q = target_qobj_transform(meas_q)
                    acquire_q = meas_q.filter(channels=[AcquireChannel(qubit)])
                    mem_slot_index = [
                        chan.index for chan in acquire_q.channels
                        if isinstance(chan, MemorySlot)
                    ][0]
                    if mem_slot_index != qubit_mem_slots[qubit]:
                        raise KeyError(
                            "The measurement calibration is not defined on "
                            "the requested classical bits")
                    sched |= meas_q
                    del qubit_mem_slots[qubit]
                    acquire_excludes[qubit] = mem_slot_index
                except KeyError:
                    pass

        if qubit_mem_slots:
            qubits = list(qubit_mem_slots.keys())
            qubit_mem_slots.update(acquire_excludes)
            meas_sched = measure(
                qubits=qubits,
                inst_map=inst_map,
                meas_map=schedule_config.meas_map,
                qubit_mem_slots=qubit_mem_slots,
            )
            meas_sched = target_qobj_transform(meas_sched)
            meas_sched = meas_sched.exclude(
                channels=[AcquireChannel(qubit) for qubit in acquire_excludes])
            sched |= meas_sched
        qubit_mem_slots.clear()
        return CircuitPulseDef(
            schedule=sched,
            qubits=[
                chan.index for chan in sched.channels
                if isinstance(chan, AcquireChannel)
            ],
        )
    def test_clbits_of_calibrated_measurements(self):
        """Test that calibrated measurements are only used when the classical bits also match."""
        q = QuantumRegister(2)
        c = ClassicalRegister(2)
        qc = QuantumCircuit(q, c)
        qc.measure(q[0], c[1])

        meas_sched = Play(Gaussian(1200, 0.2, 4), MeasureChannel(0))
        meas_sched |= Acquire(1200, AcquireChannel(0), MemorySlot(0))
        qc.add_calibration("measure", [0], meas_sched)

        sched = schedule(qc, self.backend)
        # Doesn't use the calibrated schedule because the classical memory slots do not match
        expected = Schedule(macros.measure([0], self.backend, qubit_mem_slots={0: 1}))
        self.assertEqual(sched.instructions, expected.instructions)
Exemplo n.º 13
0
    def test_pulse_name_conflicts_in_other_schedule(self):
        """Test two pulses with the same name in different schedule can be resolved."""
        backend = FakeAlmaden()

        schedules = []
        ch_d0 = pulse.DriveChannel(0)
        for amp in (0.1, 0.2):
            sched = Schedule()
            sched += Play(gaussian(duration=100, amp=amp, sigma=30, name='my_pulse'), ch_d0)
            sched += measure(qubits=[0], backend=backend) << 100
            schedules.append(sched)

        qobj = assemble(schedules, backend)

        # two user pulses and one measurement pulse should be contained
        self.assertEqual(len(qobj.config.pulse_library), 3)
Exemplo n.º 14
0
def run_with_measure(qiskit_schedule, backend_name, meas_level=1):
    try:
        from qiskit import providers, assemble
        from qiskit.pulse import DriveChannel, SetFrequency
        from qiskit.pulse.macros import measure
        from qiskit.result.result import Result

        if qiskit_schedule.duration == 0:
            return Result(backend_name, None, None, None, None, None)
        if backend_name == 'Armonk':
            backend = get_qiskit_backend(backend_name)
            pulse_sim = providers.aer.PulseSimulator.from_backend(backend)
            pulse_qobj = assemble(qiskit_schedule, backend=pulse_sim)
            measure_qubits = []
            for channel in qiskit_schedule.channels:
                if isinstance(channel, DriveChannel):
                    measure_qubits.append(channel.index)
            frequency = None
            for start_time, instruction in qiskit_schedule.instructions:
                if isinstance(instruction, SetFrequency):
                    frequency = {instruction.channel: instruction.frequency}
                    break

            def strip_frequencies(instruction):
                if isinstance(instruction[1], SetFrequency):
                    return False
                return True

            # Setting frequences isn't supported on simulators, so instead we use `schedule_los` to set a single frequency
            # and subsequently strip any SetFrequency instructions from the schedule.
            qiskit_schedule = qiskit_schedule.filter(strip_frequencies)
            qiskit_schedule += measure(measure_qubits,
                                       pulse_sim) << qiskit_schedule.duration
            pulse_qobj = assemble(qiskit_schedule,
                                  backend=pulse_sim,
                                  meas_level=meas_level,
                                  schedule_los=frequency)
            job = pulse_sim.run(pulse_qobj)
            return job.result()
        else:
            print(
                "Only FakeArmonk is supported for simulation currently because other backends are too slow"
            )
            return Result(backend_name, None, None, None, None, None)
    except ImportError:
        pass
    def test_subset_calibrated_measurements(self):
        """Test that measurement calibrations can be added and used for some qubits, even
        if the other qubits do not also have calibrated measurements."""
        qc = QuantumCircuit(3, 3)
        qc.measure(0, 0)
        qc.measure(1, 1)
        qc.measure(2, 2)
        meas_scheds = []
        for qubit in [0, 2]:
            meas = (Play(Gaussian(1200, 0.2, 4), MeasureChannel(qubit)) +
                    Acquire(1200, AcquireChannel(qubit), MemorySlot(qubit)))
            meas_scheds.append(meas)
            qc.add_calibration('measure', [qubit], meas)

        meas = macros.measure([1], FakeOpenPulse3Q())
        meas = meas.exclude(channels=[AcquireChannel(0), AcquireChannel(2)])
        sched = schedule(qc, FakeOpenPulse3Q())
        expected = Schedule(meas_scheds[0], meas_scheds[1], meas)
        self.assertEqual(sched.instructions, expected.instructions)
Exemplo n.º 16
0
    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.u2(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.u2(0, pi/2, 0)
        triple_u2_qc.u2(0, pi/2, 1)
        triple_u2_qc.u2(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)
Exemplo n.º 17
0
def drag_schedules(beta_list, qubits, pulse_amp, pulse_width,
                   pulse_sigma=None,
                   width_sigma_ratio=4, drives=None,
                   inst_map=None, meas_map=None):
    """
    Generates schedules for a drag experiment doing a pulse then
    the - pulse

    Args:
        beta_list (list of floats): List of relative amplitudes
        for the derivative pulse
        qubits (list of integers): indices of the qubits to perform a rabi
        pulse_amp (list): amp of the gaussian (list of length qubits)
        pulse_width (float): width of gaussian (in dt units)
        pulse_sigma (float): sigma of gaussian
        width_sigma_ratio (int): set sigma to a certain ratio of the width (use
            if pulse_sigma is None)
        drives (list): list of :class:`~qiskit.pulse.DriveChannel` objects
        inst_map (InstructionScheduleMap): InstructionScheduleMap object to use
        meas_map (list): meas_map to use

    Returns:
       A list of QuantumSchedules
       xdata: a list of amps

    Raises:
        QiskitError: when necessary variables are not supplied.
    """
    xdata = beta_list

    # copy the instruction to schedule mapping
    inst_map = copy.deepcopy(inst_map)

    # Following variables should not be optional.
    # To keep function interface constant, errors are inserted here.
    # TODO: redesign this function in next release
    if inst_map is None:
        QiskitError('Instruction schedule map is not provided. ',
                    'Run `backend.defaults().instruction_schedule_map` to get inst_map.')
    if meas_map is None:
        QiskitError('Measurement map is not provided. ',
                    'Run `backend.configuration().meas_map` to get meas_map.')

    if pulse_sigma is None:
        pulse_sigma = pulse_width / width_sigma_ratio

    # Construct the schedules
    drag_scheds = []
    for index, b_amp in enumerate(beta_list):
        sched = pulse.Schedule(name='dragsched_%d_0' % index)
        for qind, qubit in enumerate(qubits):
            drag_pulse_p = pulse_lib.drag(duration=pulse_width,
                                          amp=pulse_amp[qind],
                                          beta=b_amp,
                                          sigma=pulse_sigma,
                                          name='drag_pulse_%d_%d' % (index, qubit))
            drag_pulse_m = pulse_lib.drag(duration=pulse_width,
                                          amp=-pulse_amp[qind],
                                          beta=b_amp,
                                          sigma=pulse_sigma,
                                          name='drag_pulse_%d_%d' % (index, qubit))
            sched += pulse.Play(drag_pulse_p, drives[qubit])
            sched += pulse.Play(drag_pulse_m, drives[qubit])
        sched += measure(qubits, inst_map=inst_map, meas_map=meas_map).shift(2*pulse_width)
        drag_scheds.append(sched)

    return drag_scheds, xdata