Пример #1
0
def block_to_schedule(block: ScheduleBlock) -> Schedule:
    """Convert ``ScheduleBlock`` to ``Schedule``.

    Args:
        block: A ``ScheduleBlock`` to convert.

    Returns:
        Scheduled pulse program.

    Raises:
        UnassignedDurationError: When any instruction duration is not assigned.
        PulseError: When the alignment context duration is shorter than the schedule duration.

    .. note:: This transform may insert barriers in between contexts.
    """
    if not block.is_schedulable():
        raise UnassignedDurationError(
            "All instruction durations should be assigned before creating `Schedule`."
            "Please check `.parameters` to find unassigned parameter objects.")

    schedule = Schedule.initialize_from(block)

    for op_data in block.blocks:
        if isinstance(op_data, ScheduleBlock):
            context_schedule = block_to_schedule(op_data)
            if hasattr(op_data.alignment_context, "duration"):
                # context may have local scope duration, e.g. EquispacedAlignment for 1000 dt
                post_buffer = op_data.alignment_context.duration - context_schedule.duration
                if post_buffer < 0:
                    raise PulseError(
                        f"ScheduleBlock {op_data.name} has longer duration than "
                        "the specified context duration "
                        f"{context_schedule.duration} > {op_data.duration}.")
            else:
                post_buffer = 0
            schedule.append(context_schedule, inplace=True)

            # prevent interruption by following instructions.
            # padding with delay instructions is no longer necessary, thanks to alignment context.
            if post_buffer > 0:
                context_boundary = instructions.RelativeBarrier(
                    *op_data.channels)
                schedule.append(context_boundary.shift(post_buffer),
                                inplace=True)
        else:
            schedule.append(op_data, inplace=True)

    # transform with defined policy
    return block.alignment_context.align(schedule)
    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)