def test_can_construct_valid_acquire_command(self):
        """Test if valid acquire command can be constructed."""
        kernel_opts = {"start_window": 0, "stop_window": 10}
        kernel = configuration.Kernel(name="boxcar", **kernel_opts)

        discriminator_opts = {
            "neighborhoods": [{
                "qubits": 1,
                "channels": 1
            }],
            "cal": "coloring",
            "resample": False,
        }
        discriminator = configuration.Discriminator(
            name="linear_discriminator", **discriminator_opts)

        acq = instructions.Acquire(
            10,
            channels.AcquireChannel(0),
            channels.MemorySlot(0),
            kernel=kernel,
            discriminator=discriminator,
            name="acquire",
        )

        self.assertEqual(acq.duration, 10)
        self.assertEqual(acq.discriminator.name, "linear_discriminator")
        self.assertEqual(acq.discriminator.params, discriminator_opts)
        self.assertEqual(acq.kernel.name, "boxcar")
        self.assertEqual(acq.kernel.params, kernel_opts)
        self.assertIsInstance(acq.id, int)
        self.assertEqual(acq.name, "acquire")
        self.assertEqual(
            acq.operands,
            (10, channels.AcquireChannel(0), channels.MemorySlot(0), None))
Ejemplo n.º 2
0
    def test_instructions_hash(self):
        """Test hashing for acquire instruction."""
        kernel_opts = {
            'start_window': 0,
            'stop_window': 10
        }
        kernel = configuration.Kernel(name='boxcar', **kernel_opts)

        discriminator_opts = {
            'neighborhoods': [{'qubits': 1, 'channels': 1}],
            'cal': 'coloring',
            'resample': False
        }
        discriminator = configuration.Discriminator(
            name='linear_discriminator', **discriminator_opts)
        acq_1 = instructions.Acquire(10,
                                     channels.AcquireChannel(0),
                                     channels.MemorySlot(0),
                                     kernel=kernel,
                                     discriminator=discriminator,
                                     name='acquire')
        acq_2 = instructions.Acquire(10,
                                     channels.AcquireChannel(0),
                                     channels.MemorySlot(0),
                                     kernel=kernel,
                                     discriminator=discriminator,
                                     name='acquire')

        hash_1 = hash(acq_1)
        hash_2 = hash(acq_2)

        self.assertEqual(hash_1, hash_2)
Ejemplo n.º 3
0
    def test_can_construct_valid_acquire_command(self):
        """Test if valid acquire command can be constructed."""
        kernel_opts = {
            'start_window': 0,
            'stop_window': 10
        }
        kernel = configuration.Kernel(name='boxcar', **kernel_opts)

        discriminator_opts = {
            'neighborhoods': [{'qubits': 1, 'channels': 1}],
            'cal': 'coloring',
            'resample': False
        }
        discriminator = configuration.Discriminator(name='linear_discriminator',
                                                    **discriminator_opts)

        acq = instructions.Acquire(10,
                                   channels.AcquireChannel(0),
                                   channels.MemorySlot(0),
                                   kernel=kernel,
                                   discriminator=discriminator,
                                   name='acquire')

        self.assertEqual(acq.duration, 10)
        self.assertEqual(acq.discriminator.name, 'linear_discriminator')
        self.assertEqual(acq.discriminator.params, discriminator_opts)
        self.assertEqual(acq.kernel.name, 'boxcar')
        self.assertEqual(acq.kernel.params, kernel_opts)
        self.assertIsInstance(acq.id, int)
        self.assertEqual(acq.name, 'acquire')
        self.assertEqual(acq.operands, (10,
                                        channels.AcquireChannel(0),
                                        channels.MemorySlot(0), None))
Ejemplo n.º 4
0
def generate_schedule_blocks():
    """Standard QPY testcase for schedule blocks."""
    from qiskit.pulse import builder, channels, library
    from qiskit.utils import optionals

    # Parameterized schedule test is avoided.
    # Generated reference and loaded QPY object may induce parameter uuid mismatch.
    # As workaround, we need test with bounded parameters, however, schedule.parameters
    # are returned as Set and thus its order is random.
    # Since schedule parameters are validated, we cannot assign random numbers.
    # We need to upgrade testing framework.

    schedule_blocks = []

    # Instructions without parameters
    with builder.build() as block:
        with builder.align_sequential():
            builder.set_frequency(5e9, channels.DriveChannel(0))
            builder.shift_frequency(10e6, channels.DriveChannel(1))
            builder.set_phase(1.57, channels.DriveChannel(0))
            builder.shift_phase(0.1, channels.DriveChannel(1))
            builder.barrier(channels.DriveChannel(0), channels.DriveChannel(1))
            builder.play(library.Gaussian(160, 0.1, 40),
                         channels.DriveChannel(0))
            builder.play(library.GaussianSquare(800, 0.1, 64, 544),
                         channels.ControlChannel(0))
            builder.play(library.Drag(160, 0.1, 40, 1.5),
                         channels.DriveChannel(1))
            builder.play(library.Constant(800, 0.1),
                         channels.MeasureChannel(0))
            builder.acquire(1000, channels.AcquireChannel(0),
                            channels.MemorySlot(0))
    schedule_blocks.append(block)
    # Raw symbolic pulse
    if optionals.HAS_SYMENGINE:
        import symengine as sym
    else:
        import sympy as sym
    duration, amp, t = sym.symbols("duration amp t")  # pylint: disable=invalid-name
    expr = amp * sym.sin(2 * sym.pi * t / duration)
    my_pulse = library.SymbolicPulse(
        pulse_type="Sinusoidal",
        duration=100,
        parameters={"amp": 0.1},
        envelope=expr,
        valid_amp_conditions=sym.Abs(amp) <= 1.0,
    )
    with builder.build() as block:
        builder.play(my_pulse, channels.DriveChannel(0))
    schedule_blocks.append(block)
    # Raw waveform
    my_waveform = 0.1 * np.sin(2 * np.pi * np.linspace(0, 1, 100))
    with builder.build() as block:
        builder.play(my_waveform, channels.DriveChannel(0))
    schedule_blocks.append(block)

    return schedule_blocks
Ejemplo n.º 5
0
    def convert_acquire(self, instruction):
        """Return converted `AcquireInstruction`.

        Args:
            instruction (PulseQobjInstruction): acquire qobj
        Returns:
            Schedule: Converted and scheduled Instruction
        """
        t0 = instruction.t0
        duration = instruction.duration
        qubits = instruction.qubits
        discriminators = (instruction.discriminators if hasattr(
            instruction, 'discriminators') else None)

        kernels = (instruction.kernels
                   if hasattr(instruction, 'kernels') else None)

        mem_slots = instruction.memory_slot
        reg_slots = (instruction.register_slot if hasattr(
            instruction, 'register_slot') else None)

        if not isinstance(discriminators, list):
            discriminators = [discriminators for _ in range(len(qubits))]

        if not isinstance(kernels, list):
            kernels = [kernels for _ in range(len(qubits))]

        schedule = Schedule()

        for i, qubit in enumerate(qubits):
            kernel = kernels[i]
            if kernel:
                kernel = commands.Kernel(name=kernel.name,
                                         params=kernel.params)

            discriminator = discriminators[i]
            if discriminator:
                discriminator = commands.Discriminator(
                    name=discriminator.name, params=discriminator.params)

            channel = channels.AcquireChannel(qubit, buffer=self.buffer)
            if reg_slots:
                register_slot = channels.RegisterSlot(reg_slots[i])
            else:
                register_slot = None
            memory_slot = channels.MemorySlot(mem_slots[i])

            cmd = commands.Acquire(duration,
                                   discriminator=discriminator,
                                   kernel=kernel)
            schedule |= commands.AcquireInstruction(cmd, channel, memory_slot,
                                                    register_slot) << t0

        return schedule
Ejemplo n.º 6
0
    def convert_acquire(self, instruction):
        """Return converted `Acquire`.

        Args:
            instruction (PulseQobjInstruction): acquire qobj
        Returns:
            Schedule: Converted and scheduled Instruction
        """
        t0 = instruction.t0
        duration = instruction.duration
        qubits = instruction.qubits
        acquire_channels = [channels.AcquireChannel(qubit) for qubit in qubits]

        mem_slots = [channels.MemorySlot(instruction.memory_slot[i]) for i in range(len(qubits))]

        if hasattr(instruction, 'register_slot'):
            register_slots = [channels.RegisterSlot(instruction.register_slot[i])
                              for i in range(len(qubits))]
        else:
            register_slots = [None] * len(qubits)

        discriminators = (instruction.discriminators
                          if hasattr(instruction, 'discriminators') else None)
        if not isinstance(discriminators, list):
            discriminators = [discriminators]
        if any(discriminators[i] != discriminators[0] for i in range(len(discriminators))):
            warnings.warn("Can currently only support one discriminator per acquire. Defaulting "
                          "to first discriminator entry.")
        discriminator = discriminators[0]
        if discriminator:
            discriminator = Discriminator(name=discriminators[0].name, **discriminators[0].params)

        kernels = (instruction.kernels
                   if hasattr(instruction, 'kernels') else None)
        if not isinstance(kernels, list):
            kernels = [kernels]
        if any(kernels[0] != kernels[i] for i in range(len(kernels))):
            warnings.warn("Can currently only support one kernel per acquire. Defaulting to first "
                          "kernel entry.")
        kernel = kernels[0]
        if kernel:
            kernel = Kernel(name=kernels[0].name, **kernels[0].params)

        schedule = Schedule()

        for acquire_channel, mem_slot, reg_slot in zip(acquire_channels, mem_slots, register_slots):
            schedule |= instructions.Acquire(duration, acquire_channel, mem_slot=mem_slot,
                                             reg_slot=reg_slot, kernel=kernel,
                                             discriminator=discriminator) << t0

        return schedule
Ejemplo n.º 7
0
def add_implicit_acquires(schedule: ScheduleComponent,
                          meas_map: List[List[int]]) -> Schedule:
    """Return a new schedule with implicit acquires from the measurement mapping replaced by
    explicit ones.

    .. warning:: Since new acquires are being added, Memory Slots will be set to match the
                 qubit index. This may overwrite your specification.

    Args:
        schedule: Schedule to be aligned.
        meas_map: List of lists of qubits that are measured together.

    Returns:
        A ``Schedule`` with the additional acquisition instructions.
    """
    new_schedule = Schedule.initialize_from(schedule)
    acquire_map = {}

    for time, inst in schedule.instructions:
        if isinstance(inst, instructions.Acquire):
            if inst.mem_slot and inst.mem_slot.index != inst.channel.index:
                warnings.warn(
                    "One of your acquires was mapped to a memory slot which didn't match"
                    " the qubit index. I'm relabeling them to match.")

            # Get the label of all qubits that are measured with the qubit(s) in this instruction
            all_qubits = []
            for sublist in meas_map:
                if inst.channel.index in sublist:
                    all_qubits.extend(sublist)
            # Replace the old acquire instruction by a new one explicitly acquiring all qubits in
            # the measurement group.
            for i in all_qubits:
                explicit_inst = instructions.Acquire(
                    inst.duration,
                    chans.AcquireChannel(i),
                    mem_slot=chans.MemorySlot(i),
                    kernel=inst.kernel,
                    discriminator=inst.discriminator,
                )
                if time not in acquire_map:
                    new_schedule.insert(time, explicit_inst, inplace=True)
                    acquire_map = {time: {i}}
                elif i not in acquire_map[time]:
                    new_schedule.insert(time, explicit_inst, inplace=True)
                    acquire_map[time].add(i)
        else:
            new_schedule.insert(time, inst, inplace=True)

    return new_schedule
    def test_instructions_hash(self):
        """Test hashing for acquire instruction."""
        kernel_opts = {"start_window": 0, "stop_window": 10}
        kernel = configuration.Kernel(name="boxcar", **kernel_opts)

        discriminator_opts = {
            "neighborhoods": [{
                "qubits": 1,
                "channels": 1
            }],
            "cal": "coloring",
            "resample": False,
        }
        discriminator = configuration.Discriminator(
            name="linear_discriminator", **discriminator_opts)
        acq_1 = instructions.Acquire(
            10,
            channels.AcquireChannel(0),
            channels.MemorySlot(0),
            kernel=kernel,
            discriminator=discriminator,
            name="acquire",
        )
        acq_2 = instructions.Acquire(
            10,
            channels.AcquireChannel(0),
            channels.MemorySlot(0),
            kernel=kernel,
            discriminator=discriminator,
            name="acquire",
        )

        hash_1 = hash(acq_1)
        hash_2 = hash(acq_2)

        self.assertEqual(hash_1, hash_2)
    def test_relative_barrier(self):
        """Test the relative barrier directive."""
        a0 = channels.AcquireChannel(0)
        d0 = channels.DriveChannel(0)
        m0 = channels.MeasureChannel(0)
        u0 = channels.ControlChannel(0)
        mem0 = channels.MemorySlot(0)
        reg0 = channels.RegisterSlot(0)
        chans = (a0, d0, m0, u0, mem0, reg0)
        name = "barrier"
        barrier = instructions.RelativeBarrier(*chans, name=name)

        self.assertEqual(barrier.name, name)
        self.assertEqual(barrier.duration, 0)
        self.assertEqual(barrier.channels, chans)
        self.assertEqual(barrier.operands, chans)
Ejemplo n.º 10
0
def measure(qubits: List[int],
            backend=None,
            inst_map: Optional[InstructionScheduleMap] = None,
            meas_map: Optional[Union[List[List[int]], Dict[int,
                                                           List[int]]]] = None,
            qubit_mem_slots: Optional[Dict[int, int]] = None,
            measure_name: str = 'measure') -> Schedule:
    """Return a schedule which measures the requested qubits according to the given
    instruction mapping and measure map, or by using the defaults provided by the backend.

    By default, the measurement results for each qubit are trivially mapped to the qubit
    index. This behavior is overridden by qubit_mem_slots. For instance, to measure
    qubit 0 into MemorySlot(1), qubit_mem_slots can be provided as {0: 1}.

    Args:
        qubits: List of qubits to be measured.
        backend (Union[Backend, BaseBackend]): A backend instance, which contains
            hardware-specific data required for scheduling.
        inst_map: Mapping of circuit operations to pulse schedules. If None, defaults to the
                  ``instruction_schedule_map`` of ``backend``.
        meas_map: List of sets of qubits that must be measured together. If None, defaults to
                  the ``meas_map`` of ``backend``.
        qubit_mem_slots: Mapping of measured qubit index to classical bit index.
        measure_name: Name of the measurement schedule.

    Returns:
        A measurement schedule corresponding to the inputs provided.

    Raises:
        PulseError: If both ``inst_map`` or ``meas_map``, and ``backend`` is None.
    """
    schedule = Schedule(
        name="Default measurement schedule for qubits {}".format(qubits))
    try:
        inst_map = inst_map or backend.defaults().instruction_schedule_map
        meas_map = meas_map or backend.configuration().meas_map
    except AttributeError:
        raise exceptions.PulseError(
            'inst_map or meas_map, and backend cannot be None simultaneously')
    if isinstance(meas_map, list):
        meas_map = utils.format_meas_map(meas_map)

    measure_groups = set()
    for qubit in qubits:
        measure_groups.add(tuple(meas_map[qubit]))
    for measure_group_qubits in measure_groups:
        if qubit_mem_slots is not None:
            unused_mem_slots = set(measure_group_qubits) - set(
                qubit_mem_slots.values())
        try:
            default_sched = inst_map.get(measure_name, measure_group_qubits)
        except exceptions.PulseError:
            raise exceptions.PulseError(
                "We could not find a default measurement schedule called '{}'. "
                "Please provide another name using the 'measure_name' keyword "
                "argument. For assistance, the instructions which are defined are: "
                "{}".format(measure_name, inst_map.instructions))
        for time, inst in default_sched.instructions:
            if qubit_mem_slots and isinstance(inst, instructions.Acquire):
                if inst.channel.index in qubit_mem_slots:
                    mem_slot = channels.MemorySlot(
                        qubit_mem_slots[inst.channel.index])
                else:
                    mem_slot = channels.MemorySlot(unused_mem_slots.pop())
                schedule = schedule.insert(
                    time,
                    instructions.Acquire(inst.duration,
                                         inst.channel,
                                         mem_slot=mem_slot))
            elif qubit_mem_slots is None and isinstance(
                    inst, instructions.Acquire):
                schedule = schedule.insert(time, inst)
            # Measurement pulses should only be added if its qubit was measured by the user
            elif inst.channels[0].index in qubits:
                schedule = schedule.insert(time, inst)

    return schedule