コード例 #1
0
    def convert_shift_frequency(self, instruction):
        """Return converted `ShiftFrequency`.

        Args:
            instruction (PulseQobjInstruction): Shift frequency qobj instruction.

        Returns:
            Schedule: Converted and scheduled Instruction
        """
        t0 = instruction.t0
        channel = self.get_channel(instruction.ch)
        frequency = instruction.frequency * 1e9

        if isinstance(frequency, str):
            frequency_expr = parse_string_expr(frequency,
                                               partial_binding=False)

            def gen_sf_schedule(*args, **kwargs):
                _frequency = frequency_expr(*args, **kwargs)
                return instructions.ShiftFrequency(_frequency, channel) << t0

            return ParameterizedSchedule(gen_sf_schedule,
                                         parameters=frequency_expr.params)

        return instructions.ShiftFrequency(frequency, channel) << t0
コード例 #2
0
    def test_sequenced_parameterized_schedule(self):
        """Test parametrized schedule consist of multiple instruction. """
        cmd_def = CmdDef()
        converter = QobjToInstructionConverter([])
        qobjs = [PulseQobjInstruction(name='fc', ch='d0', t0=10, phase='P1'),
                 PulseQobjInstruction(name='fc', ch='d0', t0=20, phase='P2'),
                 PulseQobjInstruction(name='fc', ch='d0', t0=30, phase='P3')]
        converted_instruction = [converter(qobj) for qobj in qobjs]

        cmd_def.add('inst_seq', 0, ParameterizedSchedule(*converted_instruction, name='inst_seq'))

        with self.assertRaises(PulseError):
            cmd_def.get('inst_seq', 0, P1=1, P2=2, P3=3, P4=4, P5=5)

        with self.assertRaises(PulseError):
            cmd_def.get('inst_seq', 0, P1=1)

        with self.assertRaises(PulseError):
            cmd_def.get('inst_seq', 0, 1, 2, 3, P1=1)

        sched = cmd_def.get('inst_seq', 0, 1, 2, 3)
        self.assertEqual(sched.instructions[0][-1].command.phase, 1)
        self.assertEqual(sched.instructions[1][-1].command.phase, 2)
        self.assertEqual(sched.instructions[2][-1].command.phase, 3)

        sched = cmd_def.get('inst_seq', 0, P1=1, P2=2, P3=3)
        self.assertEqual(sched.instructions[0][-1].command.phase, 1)
        self.assertEqual(sched.instructions[1][-1].command.phase, 2)
        self.assertEqual(sched.instructions[2][-1].command.phase, 3)

        sched = cmd_def.get('inst_seq', 0, 1, 2, P3=3)
        self.assertEqual(sched.instructions[0][-1].command.phase, 1)
        self.assertEqual(sched.instructions[1][-1].command.phase, 2)
        self.assertEqual(sched.instructions[2][-1].command.phase, 3)
コード例 #3
0
    def convert_shift_phase(self, instruction):
        """Return converted `ShiftPhase`.

        Args:
            instruction (PulseQobjInstruction): phase shift qobj instruction
        Returns:
            Schedule: Converted and scheduled Instruction
        """
        t0 = instruction.t0
        channel = self.get_channel(instruction.ch)
        phase = instruction.phase

        # This is parameterized
        if isinstance(phase, str):
            phase_expr = parse_string_expr(phase, partial_binding=False)

            def gen_fc_sched(*args, **kwargs):
                # this should be real value
                _phase = phase_expr(*args, **kwargs)
                return instructions.ShiftPhase(_phase, channel) << t0

            return ParameterizedSchedule(gen_fc_sched,
                                         parameters=phase_expr.params)

        return instructions.ShiftPhase(phase, channel) << t0
コード例 #4
0
    def __init__(self, qubit_freq_est: List[float], meas_freq_est: List[float],
                 buffer: int, pulse_library: List[PulseLibraryItem],
                 cmd_def: List[Command], **kwargs: Dict[str, Any]):
        """
        Validate and reformat transport layer inputs to initialize.

        Args:
            qubit_freq_est: Estimated qubit frequencies in GHz.
            meas_freq_est: Estimated measurement cavity frequencies in GHz.
            buffer: Default buffer time (in units of dt) between pulses.
            pulse_library: Pulse name and sample definitions.
            cmd_def: Operation name and definition in terms of Commands.
            **kwargs: Other attributes for the super class.
        """
        super().__init__(**kwargs)

        self.buffer = buffer
        self.qubit_freq_est = [freq * 1e9 for freq in qubit_freq_est]
        """Qubit frequencies in Hertz."""
        self.meas_freq_est = [freq * 1e9 for freq in meas_freq_est]
        """Measurement frequencies in Hertz."""
        self.pulse_library = pulse_library
        self.cmd_def = cmd_def
        self.instruction_schedule_map = InstructionScheduleMap()

        self.converter = QobjToInstructionConverter(pulse_library)
        for inst in cmd_def:
            pulse_insts = [self.converter(inst) for inst in inst.sequence]
            schedule = ParameterizedSchedule(*pulse_insts, name=inst.name)
            self.instruction_schedule_map.add(inst.name, inst.qubits, schedule)
コード例 #5
0
    def convert_shift_frequency(self, instruction):
        """Return converted `ShiftFrequency`.

        Args:
            instruction (PulseQobjInstruction): Shift frequency qobj instruction.
                                                The input frequency is expressed  in GHz,
                                                so it will be scaled by a factor 1e9.

        Returns:
            Schedule: Converted and scheduled Instruction
        """
        t0 = instruction.t0
        channel = self.get_channel(instruction.ch)
        frequency = instruction.frequency

        if isinstance(frequency, str):
            frequency_expr = parse_string_expr(frequency,
                                               partial_binding=False)

            def gen_sf_schedule(*args, **kwargs):
                _frequency = frequency_expr(*args, **kwargs)
                return instructions.ShiftFrequency(
                    _frequency * GIGAHERTZ_TO_SI_UNITS, channel) << t0

            return ParameterizedSchedule(gen_sf_schedule,
                                         parameters=frequency_expr.params)
        else:
            frequency = frequency * GIGAHERTZ_TO_SI_UNITS

        return instructions.ShiftFrequency(frequency, channel) << t0
コード例 #6
0
    def test_multiple_parameters_not_returned(self):
        """Constructing ParameterizedSchedule object from multiple ParameterizedSchedules sharing
        arguments should not produce repeated parameters in resulting ParameterizedSchedule
        object."""

        def my_test_par_sched_one(x, y, z):
            result = Play(Waveform(np.array([x, y, z]), name="sample"), self.config.drive(0))
            return 0, result

        def my_test_par_sched_two(x, y, z):
            result = Play(Waveform(np.array([x, y, z]), name="sample"), self.config.drive(0))
            return 5, result

        par_sched_in_0 = ParameterizedSchedule(
            my_test_par_sched_one, parameters={"x": 0, "y": 1, "z": 2}
        )
        par_sched_in_1 = ParameterizedSchedule(
            my_test_par_sched_two, parameters={"x": 0, "y": 1, "z": 2}
        )
        par_sched = ParameterizedSchedule(par_sched_in_0, par_sched_in_1)
        actual = par_sched(0.01, 0.02, 0.03)
        expected = par_sched_in_0.bind_parameters(
            0.01, 0.02, 0.03
        ) | par_sched_in_1.bind_parameters(0.01, 0.02, 0.03)
        self.assertEqual(actual.start_time, expected.start_time)
        self.assertEqual(actual.stop_time, expected.stop_time)

        self.assertEqual(par_sched.parameters, ("x", "y", "z"))
コード例 #7
0
    def test_multiple_parameters_not_returned(self):
        """Constructing ParameterizedSchedule object from multiple ParameterizedSchedules sharing
        arguments should not produce repeated parameters in resulting ParameterizedSchedule
        object."""
        def my_test_par_sched_one(x, y, z):
            result = PulseInstruction(
                SamplePulse(np.array([x, y, z]), name='sample'),
                self.config.drive(0)
            )
            return 0, result

        def my_test_par_sched_two(x, y, z):
            result = PulseInstruction(
                SamplePulse(np.array([x, y, z]), name='sample'),
                self.config.drive(0)
            )
            return 5, result

        par_sched_in_0 = ParameterizedSchedule(
            my_test_par_sched_one, parameters={'x': 0, 'y': 1, 'z': 2}
        )
        par_sched_in_1 = ParameterizedSchedule(
            my_test_par_sched_two, parameters={'x': 0, 'y': 1, 'z': 2}
        )
        par_sched = ParameterizedSchedule(par_sched_in_0, par_sched_in_1)
        actual = par_sched(0.01, 0.02, 0.03)
        expected = par_sched_in_0.bind_parameters(0.01, 0.02, 0.03) |\
            par_sched_in_1.bind_parameters(0.01, 0.02, 0.03)
        self.assertEqual(actual.start_time, expected.start_time)
        self.assertEqual(actual.stop_time, expected.stop_time)

        self.assertEqual(par_sched.parameters, ('x', 'y', 'z'))
コード例 #8
0
    def test_negative_phases(self):
        """Test bind parameters with negative values."""
        cmd_def = CmdDef()
        converter = QobjToInstructionConverter([])
        qobjs = [PulseQobjInstruction(name='fc', ch='d0', t0=10, phase='P1'),
                 PulseQobjInstruction(name='fc', ch='d0', t0=20, phase='-(P2)')]
        converted_instruction = [converter(qobj) for qobj in qobjs]

        cmd_def.add('inst_seq', 0, ParameterizedSchedule(*converted_instruction, name='inst_seq'))

        sched = cmd_def.get('inst_seq', 0, -1, 2)

        self.assertEqual(sched.instructions[0][-1].command.phase, -1)
        self.assertEqual(sched.instructions[1][-1].command.phase, -2)
コード例 #9
0
    def test_filter(self):
        """Test _filter method."""
        device = self.two_qubit_device
        lp0 = self.linear(duration=3, slope=0.2, intercept=0.1)
        sched = Schedule(name='fake_experiment')
        sched = sched.insert(0, lp0(device.drives[0]))
        sched = sched.insert(10, lp0(device.drives[1]))
        sched = sched.insert(30, FrameChange(phase=-1.57)(device.drives[0]))
        for i in sched._filter([lambda x: True]).instructions:
            self.assertTrue(i in sched.instructions)
        self.assertEqual(len(sched._filter([lambda x: False]).instructions), 0)
        self.assertEqual(
            len(sched._filter([lambda x: x[0] < 30]).instructions), 2)

        def my_test_par_sched_one(x, y, z):
            result = PulseInstruction(
                SamplePulse(np.array([x, y, z]), name='sample'),
                device.drives[0])
            return 0, result

        def my_test_par_sched_two(x, y, z):
            result = PulseInstruction(
                SamplePulse(np.array([x, y, z]), name='sample'),
                device.drives[0])
            return 5, result

        par_sched_in_0 = ParameterizedSchedule(my_test_par_sched_one,
                                               parameters={
                                                   'x': 0,
                                                   'y': 1,
                                                   'z': 2
                                               })
        par_sched_in_1 = ParameterizedSchedule(my_test_par_sched_two,
                                               parameters={
                                                   'x': 0,
                                                   'y': 1,
                                                   'z': 2
                                               })
        par_sched = ParameterizedSchedule(par_sched_in_0, par_sched_in_1)

        cmd_def = CmdDef()
        cmd_def.add('test', 0, par_sched)

        actual = cmd_def.get('test', 0, 0.01, 0.02, 0.03)
        expected = par_sched_in_0.bind_parameters(0.01, 0.02, 0.03) |\
            par_sched_in_1.bind_parameters(0.01, 0.02, 0.03)
        self.assertEqual(actual.start_time, expected.start_time)
        self.assertEqual(actual.stop_time, expected.stop_time)

        self.assertEqual(cmd_def.get_parameters('test', 0), ('x', 'y', 'z'))
コード例 #10
0
    def test_sequenced_parameterized_schedule(self):
        """Test parametrized schedule consists of multiple instruction. """

        converter = QobjToInstructionConverter([], buffer=0)
        qobjs = [
            PulseQobjInstruction(name='fc', ch='d0', t0=10, phase='P1'),
            PulseQobjInstruction(name='fc', ch='d0', t0=20, phase='P2'),
            PulseQobjInstruction(name='fc', ch='d0', t0=30, phase='P3')
        ]
        converted_instruction = [converter(qobj) for qobj in qobjs]

        inst_map = InstructionScheduleMap()

        inst_map.add(
            'inst_seq', 0,
            ParameterizedSchedule(*converted_instruction, name='inst_seq'))

        with self.assertRaises(PulseError):
            inst_map.get('inst_seq', 0, P1=1, P2=2, P3=3, P4=4, P5=5)

        with self.assertRaises(PulseError):
            inst_map.get('inst_seq', 0, P1=1)

        with self.assertRaises(PulseError):
            inst_map.get('inst_seq', 0, 1, 2, 3, P1=1)

        p3_expr = Parameter('p3')
        p3_expr = p3_expr.bind({p3_expr: 3})

        sched = inst_map.get('inst_seq', 0, 1, 2, p3_expr)
        self.assertEqual(sched.instructions[0][-1].phase, 1)
        self.assertEqual(sched.instructions[1][-1].phase, 2)
        self.assertEqual(sched.instructions[2][-1].phase, 3)

        sched = inst_map.get('inst_seq', 0, P1=1, P2=2, P3=p3_expr)
        self.assertEqual(sched.instructions[0][-1].phase, 1)
        self.assertEqual(sched.instructions[1][-1].phase, 2)
        self.assertEqual(sched.instructions[2][-1].phase, 3)

        sched = inst_map.get('inst_seq', 0, 1, 2, P3=p3_expr)
        self.assertEqual(sched.instructions[0][-1].phase, 1)
        self.assertEqual(sched.instructions[1][-1].phase, 2)
        self.assertEqual(sched.instructions[2][-1].phase, 3)
コード例 #11
0
    def test_multiple_parameters_not_returned(self):
        """Constructing ParameterizedSchedule object from multiple ParameterizedSchedules sharing
        arguments should not produce repeated parameters in resulting ParameterizedSchedule
        object."""
        device = self.two_qubit_device

        def my_test_par_sched_one(x, y, z):
            result = PulseInstruction(
                SamplePulse(np.array([x, y, z]), name='sample'),
                device.drives[0])
            return 0, result

        def my_test_par_sched_two(x, y, z):
            result = PulseInstruction(
                SamplePulse(np.array([x, y, z]), name='sample'),
                device.drives[0])
            return 5, result

        par_sched_in_0 = ParameterizedSchedule(my_test_par_sched_one,
                                               parameters={
                                                   'x': 0,
                                                   'y': 1,
                                                   'z': 2
                                               })
        par_sched_in_1 = ParameterizedSchedule(my_test_par_sched_two,
                                               parameters={
                                                   'x': 0,
                                                   'y': 1,
                                                   'z': 2
                                               })
        par_sched = ParameterizedSchedule(par_sched_in_0, par_sched_in_1)

        cmd_def = CmdDef()
        cmd_def.add('test', 0, par_sched)

        actual = cmd_def.get('test', 0, 0.01, 0.02, 0.03)
        expected = par_sched_in_0.bind_parameters(0.01, 0.02, 0.03) |\
            par_sched_in_1.bind_parameters(0.01, 0.02, 0.03)
        self.assertEqual(actual.start_time, expected.start_time)
        self.assertEqual(actual.stop_time, expected.stop_time)

        self.assertEqual(cmd_def.get_parameters('test', 0), ('x', 'y', 'z'))
コード例 #12
0
    def convert_persistent_value(self, instruction):
        """Return converted `PersistentValueInstruction`.

        Args:
            instruction (PulseQobjInstruction): persistent value qobj
        Returns:
            Schedule: Converted and scheduled Instruction
        """
        t0 = instruction.t0
        channel = self.get_channel(instruction.ch)
        val = instruction.val

        # This is parameterized
        if isinstance(val, str):
            val_expr = parse_string_expr(val, partial_binding=False)

            def gen_pv_sched(*args, **kwargs):
                val = complex(val_expr(*args, **kwargs))
                return commands.PersistentValue(val)(channel) << t0

            return ParameterizedSchedule(gen_pv_sched, parameters=val_expr.params)

        return commands.PersistentValue(val)(channel) << t0
コード例 #13
0
    def convert_frame_change(self, instruction):
        """Return converted `FrameChangeInstruction`.

        Args:
            instruction (PulseQobjInstruction): frame change qobj
        Returns:
            Schedule: Converted and scheduled Instruction
        """
        t0 = instruction.t0
        channel = self.get_channel(instruction.ch)
        phase = instruction.phase

        # This is parameterized
        if isinstance(phase, str):
            phase_expr, params = _parse_string_expr(phase)

            def gen_fc_sched(*args, **kwargs):
                phase = abs(phase_expr(*args, **kwargs))
                return commands.FrameChange(phase)(channel) << t0

            return ParameterizedSchedule(gen_fc_sched, parameters=params)

        return commands.FrameChange(phase)(channel) << t0
コード例 #14
0
def update_u_gates(drag_params, pi2_pulse_schedules=None,
                   qubits=None, inst_map=None, cmd_def=None, drives=None):
    """Update the cmd_def with new single qubit gate values

    Will update U2, U3

    Args:
        drag_params: list of drag params
        pi2_pulse_schedules: list of new pi/2 gate as a pulse schedule
                             will use the drag_params if this is None.
        qubits: list of qubits to update
        inst_map: InstructionScheduleMap providing circuit instruction to
                  schedule definitions.
        cmd_def: CmdDef object for the device (deprecated)
        drives: List of drive chs

    Returns:
        updated cmd_def
    """

    # U2 is -P1.Y90p.-P0
    # U3 is -P2.X90p.-P0.X90m.-P1

    if cmd_def and not inst_map:
        inst_map = cmd_def

    def parametrized_fc(kw_name, phi0, chan, t_offset):
        def _parametrized_fc(**kwargs):
            return FrameChange(phase=-kwargs[kw_name]+phi0)(chan) << t_offset
        return _parametrized_fc

    for qubit in qubits:

        drive_ch = drives[qubit]

        if pi2_pulse_schedules is None:
            x90_pulse = pulse_lib.drag(**drag_params[qubit])
            x90_pulse = Schedule(x90_pulse(drive_ch))
        else:
            x90_pulse = pi2_pulse_schedules[qubit]

        pulse_dur = x90_pulse.duration

        # find channel dependency for u2
        for _u2_group in _find_channel_groups('u2',
                                              qubits=qubit,
                                              inst_map=inst_map):
            if drive_ch in _u2_group:
                break
        else:
            _u2_group = (drive_ch, )

        u2_fc1s = [parametrized_fc('P1', np.pi/2, ch, 0)
                   for ch in _u2_group]
        u2_fc2s = [parametrized_fc('P0', -np.pi/2, ch, pulse_dur)
                   for ch in _u2_group]

        # find channel dependency for u2
        for _u3_group in _find_channel_groups('u3',
                                              qubits=qubit,
                                              inst_map=inst_map):
            if drive_ch in _u3_group:
                break
        else:
            _u3_group = (drive_ch, )

        u3_fc1s = [parametrized_fc('P2', 0, ch, 0) for ch in _u3_group]
        u3_fc2s = [parametrized_fc('P0', -np.pi, ch, pulse_dur)
                   for ch in _u3_group]
        u3_fc3s = [parametrized_fc('P1', np.pi, ch, 2*pulse_dur)
                   for ch in _u3_group]

        # add commands to schedule
        # u2
        schedule1 = ParameterizedSchedule(*[*u2_fc1s,
                                            x90_pulse,
                                            *u2_fc2s],
                                          parameters=['P0', 'P1'],
                                          name='u2_%d' % qubit)

        # u3
        schedule2 = ParameterizedSchedule(*[*u3_fc1s,
                                            x90_pulse,
                                            *u3_fc2s,
                                            x90_pulse << pulse_dur,
                                            *u3_fc3s],
                                          parameters=['P0', 'P1', 'P2'],
                                          name='u3_%d' % qubit)

        inst_map.add('u2', qubits=qubit, schedule=schedule1)
        inst_map.add('u3', qubits=qubit, schedule=schedule2)
コード例 #15
0
def update_u_gates(drag_params, pi2_pulse_schedules=None,
                   qubits=None, inst_map=None, drives=None):
    """Update the cmd_def with new single qubit gate values

    Will update U2, U3

    Args:
        drag_params (list): list of drag params
        pi2_pulse_schedules (list): list of new pi/2 gate as a pulse schedule
                             will use the drag_params if this is None.
        qubits (list): list of qubits to update
        inst_map (InstructionScheduleMap): InstructionScheduleMap providing
            circuit instruction to schedule definitions.
        drives (list): List of drive chs
    """

    # U2 is -P1.Y90p.-P0
    # U3 is -P2.X90p.-P0.X90m.-P1

    def parametrized_fc(kw_name, phi0, chan, t_offset):
        def _parametrized_fc(**kwargs):
            return ShiftPhase(phase=-kwargs[kw_name]+phi0, channel=chan).shift(t_offset)
        return _parametrized_fc

    for qubit in qubits:

        drive_ch = drives[qubit]

        if pi2_pulse_schedules is None:
            x90_pulse = pulse_lib.drag(**drag_params[qubit])
            x90_sched = Schedule()
            x90_sched += Play(x90_pulse, drive_ch).shift(0)
        else:
            x90_sched = pi2_pulse_schedules[qubit]

        pulse_dur = x90_sched.duration

        # find channel dependency for u2
        for _u2_group in _find_channel_groups('u2', qubits=qubit, inst_map=inst_map):
            if drive_ch in _u2_group:
                break
        else:
            _u2_group = (drive_ch, )

        u2_fc1s = [parametrized_fc('P1', np.pi/2, ch, 0) for ch in _u2_group]
        u2_fc2s = [parametrized_fc('P0', -np.pi/2, ch, pulse_dur) for ch in _u2_group]

        # find channel dependency for u3
        for _u3_group in _find_channel_groups('u3', qubits=qubit, inst_map=inst_map):
            if drive_ch in _u3_group:
                break
        else:
            _u3_group = (drive_ch, )

        u3_fc1s = [parametrized_fc('P2', 0, ch, 0) for ch in _u3_group]
        u3_fc2s = [parametrized_fc('P0', -np.pi, ch, pulse_dur) for ch in _u3_group]
        u3_fc3s = [parametrized_fc('P1', np.pi, ch, 2*pulse_dur) for ch in _u3_group]

        # add commands to schedule
        # u2
        sched_components = [*u2_fc1s, x90_sched, *u2_fc2s]
        schedule1 = ParameterizedSchedule(*sched_components,
                                          parameters=['P0', 'P1'], name='u2_%d' % qubit)

        # u3
        sched_components = [*u3_fc1s, x90_sched, *u3_fc2s, x90_sched.shift(pulse_dur), *u3_fc3s]
        schedule2 = ParameterizedSchedule(*sched_components,
                                          parameters=['P0', 'P1', 'P2'], name='u3_%d' % qubit)

        inst_map.add('u2', qubits=qubit, schedule=schedule1)
        inst_map.add('u3', qubits=qubit, schedule=schedule2)