예제 #1
0
    def test_snapshot(self):
        """Test converted qobj from Snapshot."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        instruction = Snapshot(label='label', snapshot_type='type')

        valid_qobj = PulseQobjInstruction(name='snapshot',
                                          t0=0,
                                          label='label',
                                          type='type')

        self.assertEqual(converter(0, instruction), valid_qobj)
예제 #2
0
    def test_deprecated_drive_instruction(self):
        """Test converted qobj from PulseInstruction."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        with self.assertWarns(DeprecationWarning):
            command = SamplePulse(np.arange(0, 0.01), name='linear')
        with self.assertWarns(DeprecationWarning):
            instruction = command(DriveChannel(0))

        valid_qobj = PulseQobjInstruction(name='linear', ch='d0', t0=0)

        self.assertEqual(converter(0, instruction), valid_qobj)
예제 #3
0
    def test_set_frequency(self):
        """Test converted qobj from SetFrequency."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        instruction = SetFrequency(8.0e9, DriveChannel(0))

        valid_qobj = PulseQobjInstruction(name='setf',
                                          ch='d0',
                                          t0=0,
                                          frequency=8.0)

        self.assertEqual(converter(0, instruction), valid_qobj)
예제 #4
0
    def test_set_phase(self):
        """Test converted qobj from FrameChangeInstruction."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        instruction = SetPhase(3.14, DriveChannel(0))

        valid_qobj = PulseQobjInstruction(name='setp',
                                          ch='d0',
                                          t0=0,
                                          phase=3.14)

        self.assertEqual(converter(0, instruction), valid_qobj)
예제 #5
0
    def test_gaussian_square_pulse_instruction(self):
        """Test that parametric pulses are correctly converted to PulseQobjInstructions."""
        converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2)
        instruction = Play(GaussianSquare(duration=1500, sigma=15, amp=-0.5 + 0.2j, width=1300),
                           MeasureChannel(1))

        valid_qobj = PulseQobjInstruction(
            name='parametric_pulse',
            pulse_shape='gaussian_square',
            ch='m1',
            t0=10,
            parameters={'duration': 1500, 'sigma': 15, 'amp': -0.5 + 0.2j, 'width': 1300})
        self.assertEqual(converter(10, instruction), valid_qobj)
예제 #6
0
    def test_drive_instruction(self):
        """Test converted qobj from PulseInstruction."""
        converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2)
        command = SamplePulse(np.arange(0, 0.01), name='linear')
        instruction = command(self.device.q[0].drive)

        valid_qobj = PulseQobjInstruction(
            name='linear',
            ch='d0',
            t0=0
        )

        self.assertEqual(converter(0, instruction), valid_qobj)
예제 #7
0
    def test_persistent_value(self):
        """Test converted qobj from PersistentValueInstruction."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        with self.assertWarns(DeprecationWarning):
            command = PersistentValue(value=0.1j)
        with self.assertWarns(DeprecationWarning):
            instruction = command(DriveChannel(0))

        valid_qobj = PulseQobjInstruction(name='pv', ch='d0', t0=0, val=0.1j)

        with self.assertWarns(DeprecationWarning):
            self.assertEqual(converter(0, instruction), valid_qobj)
예제 #8
0
    def test_deprecated_gaussian_pulse_instruction(self):
        """Test that parametric pulses are correctly converted to PulseQobjInstructions."""
        converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2)
        with self.assertWarns(DeprecationWarning):
            instruction = Gaussian(duration=25, sigma=15, amp=-0.5 + 0.2j)(DriveChannel(0))

        valid_qobj = PulseQobjInstruction(
            name='parametric_pulse',
            pulse_shape='gaussian',
            ch='d0',
            t0=0,
            parameters={'duration': 25, 'sigma': 15, 'amp': -0.5 + 0.2j})
        self.assertEqual(converter(0, instruction), valid_qobj)
예제 #9
0
    def test_persistent_value(self):
        """Test converted qobj from PersistentValueInstruction."""
        converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2)
        command = PersistentValue(value=0.1j)
        instruction = command(self.device.q[0].drive)

        valid_qobj = PulseQobjInstruction(
            name='pv',
            ch='d0',
            t0=0,
            val=0.1j
        )

        self.assertEqual(converter(0, instruction), valid_qobj)
예제 #10
0
    def test_frame_change(self):
        """Test converted qobj from FrameChangeInstruction."""
        converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2)
        command = FrameChange(phase=0.1)
        instruction = command(self.device.q[0].drive)

        valid_qobj = PulseQobjInstruction(
            name='fc',
            ch='d0',
            t0=0,
            phase=0.1
        )

        self.assertEqual(converter(0, instruction), valid_qobj)
예제 #11
0
    def test_frame_change(self):
        """Test converted qobj from FrameChangeInstruction."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        with self.assertWarns(DeprecationWarning):
            command = FrameChange(phase=0.1)
        with self.assertWarns(DeprecationWarning):
            instruction = command(DriveChannel(0))

        valid_qobj = PulseQobjInstruction(name='fc', ch='d0', t0=0, phase=0.1)

        self.assertEqual(converter(0, instruction), valid_qobj)
        instruction = ShiftPhase(0.1, DriveChannel(0))
        self.assertEqual(converter(0, instruction), valid_qobj)
예제 #12
0
    def test_constant_pulse_instruction(self):
        """Test that parametric pulses are correctly converted to PulseQobjInstructions."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        instruction = Play(Constant(duration=25, amp=1), ControlChannel(2))

        valid_qobj = PulseQobjInstruction(name='parametric_pulse',
                                          pulse_shape='constant',
                                          ch='u2',
                                          t0=20,
                                          parameters={
                                              'duration': 25,
                                              'amp': 1
                                          })
        self.assertEqual(converter(20, instruction), valid_qobj)
    def test_constant_pulse_instruction(self):
        """Test that parametric pulses are correctly converted to PulseQobjInstructions."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        instruction = Play(Constant(duration=25, amp=1), ControlChannel(2))

        valid_qobj = PulseQobjInstruction(
            name="parametric_pulse",
            pulse_shape="constant",
            ch="u2",
            t0=20,
            parameters={
                "duration": 25,
                "amp": 1
            },
        )
        self.assertEqual(converter(20, instruction), valid_qobj)
 def test_gaussian_pulse_instruction(self):
     """Test that parametric pulses are correctly converted to PulseQobjInstructions."""
     converter = InstructionToQobjConverter(PulseQobjInstruction,
                                            meas_level=2)
     instruction = Play(Gaussian(duration=25, sigma=15, amp=-0.5 + 0.2j),
                        DriveChannel(0))
     valid_qobj = PulseQobjInstruction(
         name="parametric_pulse",
         pulse_shape="gaussian",
         ch="d0",
         t0=0,
         parameters={
             "duration": 25,
             "sigma": 15,
             "amp": -0.5 + 0.2j
         },
     )
     self.assertEqual(converter(0, instruction), valid_qobj)
예제 #15
0
    def test_drag_pulse_instruction(self):
        """Test that parametric pulses are correctly converted to PulseQobjInstructions."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        instruction = Drag(duration=25, sigma=15, amp=-0.5 + 0.2j,
                           beta=0.5)(DriveChannel(0))

        valid_qobj = PulseQobjInstruction(name='parametric_pulse',
                                          pulse_shape='drag',
                                          ch='d0',
                                          t0=30,
                                          parameters={
                                              'duration': 25,
                                              'sigma': 15,
                                              'amp': -0.5 + 0.2j,
                                              'beta': 0.5
                                          })
        self.assertEqual(converter(30, instruction), valid_qobj)
예제 #16
0
    def test_acquire(self):
        """Test converted qobj from AcquireInstruction."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        instruction = Acquire(10, AcquireChannel(0), MemorySlot(0),
                              RegisterSlot(0))
        valid_qobj = PulseQobjInstruction(name='acquire',
                                          t0=0,
                                          duration=10,
                                          qubits=[0],
                                          memory_slot=[0],
                                          register_slot=[0])
        self.assertEqual(converter(0, instruction), valid_qobj)

        # without register
        instruction = Acquire(10, AcquireChannel(0), MemorySlot(0))
        valid_qobj = PulseQobjInstruction(name='acquire',
                                          t0=0,
                                          duration=10,
                                          qubits=[0],
                                          memory_slot=[0])
        self.assertEqual(converter(0, instruction), valid_qobj)
    def test_gaussian_square_pulse_instruction(self):
        """Test that parametric pulses are correctly converted to PulseQobjInstructions."""
        converter = InstructionToQobjConverter(PulseQobjInstruction,
                                               meas_level=2)
        instruction = Play(
            GaussianSquare(duration=1500,
                           sigma=15,
                           amp=-0.5 + 0.2j,
                           width=1300), MeasureChannel(1))

        valid_qobj = PulseQobjInstruction(
            name="parametric_pulse",
            pulse_shape="gaussian_square",
            ch="m1",
            t0=10,
            parameters={
                "duration": 1500,
                "sigma": 15,
                "amp": -0.5 + 0.2j,
                "width": 1300
            },
        )
        self.assertEqual(converter(10, instruction), valid_qobj)
def _assemble_instructions(
    schedule: pulse.Schedule,
    instruction_converter: converters.InstructionToQobjConverter,
    run_config: RunConfig, user_pulselib: Dict[str, List[complex]]
) -> Tuple[List[qobj.PulseQobjInstruction], int]:
    """Assembles the instructions in a schedule into a list of PulseQobjInstructions and returns
    related metadata that will be assembled into the Qobj configuration. Lookup table for
    pulses defined in all experiments are registered in ``user_pulselib``. This object should be
    mutable python dictionary so that items are properly updated after each instruction assemble.
    The dictionary is not returned to avoid redundancy.

    Args:
        schedule: Schedule to assemble.
        instruction_converter: A converter instance which can convert PulseInstructions to
                               PulseQobjInstructions.
        run_config: Configuration of the runtime environment.
        user_pulselib: User pulse library from previous schedule.

    Returns:
        A list of converted instructions, the user pulse library dictionary (from pulse name to
        pulse samples), and the maximum number of readout memory slots used by this Schedule.
    """
    max_memory_slot = 0
    qobj_instructions = []

    acquire_instruction_map = defaultdict(list)
    for time, instruction in schedule.instructions:

        if (isinstance(instruction, instructions.Play)
                and isinstance(instruction.pulse, library.ParametricPulse)):
            pulse_shape = ParametricPulseShapes(type(instruction.pulse)).name
            if pulse_shape not in run_config.parametric_pulses:
                instruction = instructions.Play(
                    instruction.pulse.get_waveform(),
                    instruction.channel,
                    name=instruction.name)

        if (isinstance(instruction, instructions.Play)
                and isinstance(instruction.pulse, library.Waveform)):
            name = hashlib.sha256(instruction.pulse.samples).hexdigest()
            instruction = instructions.Play(library.Waveform(
                name=name, samples=instruction.pulse.samples),
                                            channel=instruction.channel,
                                            name=name)
            user_pulselib[name] = instruction.pulse.samples

        if isinstance(instruction, instructions.Acquire):
            if instruction.mem_slot:
                max_memory_slot = max(max_memory_slot,
                                      instruction.mem_slot.index)
            # Acquires have a single AcquireChannel per inst, but we have to bundle them
            # together into the Qobj as one instruction with many channels
            acquire_instruction_map[(time,
                                     instruction.duration)].append(instruction)
            continue

        if isinstance(instruction,
                      (instructions.Delay, instructions.Directive)):
            # delay instructions are ignored as timing is explicit within qobj
            continue

        qobj_instructions.append(instruction_converter(time, instruction))

    if acquire_instruction_map:
        if hasattr(run_config, 'meas_map'):
            _validate_meas_map(acquire_instruction_map, run_config.meas_map)
        for (time, _), instrs in acquire_instruction_map.items():
            qobj_instructions.append(
                instruction_converter.convert_bundled_acquires(time, instrs), )

    return qobj_instructions, max_memory_slot
def _assemble_instructions(
    sched: Union[pulse.Schedule, pulse.ScheduleBlock],
    instruction_converter: converters.InstructionToQobjConverter,
    run_config: RunConfig,
    user_pulselib: Dict[str, List[complex]],
) -> Tuple[List[qobj.PulseQobjInstruction], int]:
    """Assembles the instructions in a schedule into a list of PulseQobjInstructions and returns
    related metadata that will be assembled into the Qobj configuration. Lookup table for
    pulses defined in all experiments are registered in ``user_pulselib``. This object should be
    mutable python dictionary so that items are properly updated after each instruction assemble.
    The dictionary is not returned to avoid redundancy.

    Args:
        sched: Schedule to assemble.
        instruction_converter: A converter instance which can convert PulseInstructions to
                               PulseQobjInstructions.
        run_config: Configuration of the runtime environment.
        user_pulselib: User pulse library from previous schedule.

    Returns:
        A list of converted instructions, the user pulse library dictionary (from pulse name to
        pulse samples), and the maximum number of readout memory slots used by this Schedule.
    """
    sched = transforms.target_qobj_transform(sched)

    max_memory_slot = 0
    qobj_instructions = []

    acquire_instruction_map = defaultdict(list)
    for time, instruction in sched.instructions:

        if isinstance(instruction, instructions.Play):
            if isinstance(instruction.pulse, (library.ParametricPulse, library.SymbolicPulse)):
                is_backend_supported = True
                try:
                    pulse_shape = ParametricPulseShapes(type(instruction.pulse)).name
                    if pulse_shape not in run_config.parametric_pulses:
                        is_backend_supported = False
                except ValueError:
                    # Custom pulse class, or bare SymbolicPulse object.
                    is_backend_supported = False

                if not is_backend_supported:
                    instruction = instructions.Play(
                        instruction.pulse.get_waveform(), instruction.channel, name=instruction.name
                    )

            if isinstance(instruction.pulse, library.Waveform):
                name = hashlib.sha256(instruction.pulse.samples).hexdigest()
                instruction = instructions.Play(
                    library.Waveform(name=name, samples=instruction.pulse.samples),
                    channel=instruction.channel,
                    name=name,
                )
                user_pulselib[name] = instruction.pulse.samples

        # ignore explicit delay instrs on acq channels as they are invalid on IBMQ backends;
        # timing of other instrs will still be shifted appropriately
        if isinstance(instruction, instructions.Delay) and isinstance(
            instruction.channel, channels.AcquireChannel
        ):
            continue

        if isinstance(instruction, instructions.Acquire):
            if instruction.mem_slot:
                max_memory_slot = max(max_memory_slot, instruction.mem_slot.index)
            # Acquires have a single AcquireChannel per inst, but we have to bundle them
            # together into the Qobj as one instruction with many channels
            acquire_instruction_map[(time, instruction.duration)].append(instruction)
            continue

        qobj_instructions.append(instruction_converter(time, instruction))

    if acquire_instruction_map:
        if hasattr(run_config, "meas_map"):
            _validate_meas_map(acquire_instruction_map, run_config.meas_map)
        for (time, _), instrs in acquire_instruction_map.items():
            qobj_instructions.append(
                instruction_converter.convert_bundled_acquires(time, instrs),
            )

    return qobj_instructions, max_memory_slot
예제 #20
0
def _assemble_instructions(
    schedule: Schedule, instruction_converter: InstructionToQobjConverter,
    run_config: RunConfig,
    user_pulselib: Dict[str,
                        Command]) -> Tuple[List[PulseQobjInstruction], int]:
    """Assembles the instructions in a schedule into a list of PulseQobjInstructions and returns
    related metadata that will be assembled into the Qobj configuration. Lookup table for
    pulses defined in all experiments are registered in ``user_pulselib``. This object should be
    mutable python dictionary so that items are properly updated after each instruction assemble.
    The dictionary is not returned to avoid redundancy.

    Args:
        schedule: Schedule to assemble.
        instruction_converter: A converter instance which can convert PulseInstructions to
                               PulseQobjInstructions.
        run_config: Configuration of the runtime environment.
        user_pulselib: User pulse library from previous schedule.

    Returns:
        A list of converted instructions, the user pulse library dictionary (from pulse name to
        pulse command), and the maximum number of readout memory slots used by this Schedule.
    """
    max_memory_slot = 0
    qobj_instructions = []

    acquire_instruction_map = defaultdict(list)
    for time, instruction in schedule.instructions:

        if isinstance(instruction, ParametricInstruction):
            pulse_shape = ParametricPulseShapes(type(instruction.command)).name
            if pulse_shape not in run_config.parametric_pulses:
                # Convert to SamplePulse if the backend does not support it
                instruction = PulseInstruction(
                    instruction.command.get_sample_pulse(),
                    instruction.channels[0],
                    name=instruction.name)

        if isinstance(instruction, PulseInstruction):
            name = instruction.command.name
            if name in user_pulselib and instruction.command != user_pulselib[
                    name]:
                name = "{0}-{1:x}".format(
                    name, hash(instruction.command.samples.tostring()))
                instruction = PulseInstruction(command=SamplePulse(
                    name=name, samples=instruction.command.samples),
                                               name=instruction.name,
                                               channel=instruction.channels[0])
            # add samples to pulse library
            user_pulselib[name] = instruction.command

        if isinstance(instruction, AcquireInstruction):
            max_memory_slot = max(
                max_memory_slot,
                *[slot.index for slot in instruction.mem_slots])
            # Acquires have a single AcquireChannel per inst, but we have to bundle them
            # together into the Qobj as one instruction with many channels
            acquire_instruction_map[(time,
                                     instruction.command)].append(instruction)
            continue

        if isinstance(instruction, (DelayInstruction, Delay)):
            # delay instructions are ignored as timing is explicit within qobj
            continue

        qobj_instructions.append(instruction_converter(time, instruction))

    if acquire_instruction_map:
        if hasattr(run_config, 'meas_map'):
            _validate_meas_map(acquire_instruction_map, run_config.meas_map)
        for (time, _), instructions in acquire_instruction_map.items():
            qubits, mem_slots, reg_slots = _bundle_channel_indices(
                instructions)
            qobj_instructions.append(
                instruction_converter.convert_single_acquires(
                    time,
                    instructions[0],
                    qubits=qubits,
                    memory_slot=mem_slots,
                    register_slot=reg_slots))

    return qobj_instructions, max_memory_slot