def test_insert_dd_ghz_everywhere(self):
        """Test DD gates even on initial idle spots.

                   ┌───┐            ┌────────────────┐┌───┐┌────────────────┐┌───┐»
        q_0: ──────┤ H ├─────────■──┤ Delay(100[dt]) ├┤ Y ├┤ Delay(200[dt]) ├┤ Y ├»
             ┌─────┴───┴─────┐ ┌─┴─┐└────────────────┘└───┘└────────────────┘└───┘»
        q_1: ┤ Delay(50[dt]) ├─┤ X ├───────────────────────────────────────────■──»
             ├───────────────┴┐├───┤┌────────────────┐┌───┐┌────────────────┐┌─┴─┐»
        q_2: ┤ Delay(162[dt]) ├┤ Y ├┤ Delay(326[dt]) ├┤ Y ├┤ Delay(162[dt]) ├┤ X ├»
             ├────────────────┤├───┤├────────────────┤├───┤├────────────────┤└───┘»
        q_3: ┤ Delay(212[dt]) ├┤ Y ├┤ Delay(426[dt]) ├┤ Y ├┤ Delay(212[dt]) ├─────»
             └────────────────┘└───┘└────────────────┘└───┘└────────────────┘     »
        «     ┌────────────────┐
        «q_0: ┤ Delay(100[dt]) ├─────────────────────────────────────────────
        «     ├───────────────┬┘┌───┐┌────────────────┐┌───┐┌───────────────┐
        «q_1: ┤ Delay(50[dt]) ├─┤ Y ├┤ Delay(100[dt]) ├┤ Y ├┤ Delay(50[dt]) ├
        «     └───────────────┘ └───┘└────────────────┘└───┘└───────────────┘
        «q_2: ────────■──────────────────────────────────────────────────────
        «           ┌─┴─┐
        «q_3: ──────┤ X ├────────────────────────────────────────────────────
        «           └───┘
        """
        dd_sequence = [YGate(), YGate()]
        pm = PassManager([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(self.durations,
                                   dd_sequence,
                                   skip_reset_qubits=False),
        ])

        ghz4_dd = pm.run(self.ghz4)

        expected = self.ghz4.copy()
        expected = expected.compose(Delay(50), [1], front=True)

        expected = expected.compose(Delay(162), [2], front=True)
        expected = expected.compose(YGate(), [2], front=True)
        expected = expected.compose(Delay(326), [2], front=True)
        expected = expected.compose(YGate(), [2], front=True)
        expected = expected.compose(Delay(162), [2], front=True)

        expected = expected.compose(Delay(212), [3], front=True)
        expected = expected.compose(YGate(), [3], front=True)
        expected = expected.compose(Delay(426), [3], front=True)
        expected = expected.compose(YGate(), [3], front=True)
        expected = expected.compose(Delay(212), [3], front=True)

        expected = expected.compose(Delay(100), [0])
        expected = expected.compose(YGate(), [0])
        expected = expected.compose(Delay(200), [0])
        expected = expected.compose(YGate(), [0])
        expected = expected.compose(Delay(100), [0])

        expected = expected.compose(Delay(50), [1])
        expected = expected.compose(YGate(), [1])
        expected = expected.compose(Delay(100), [1])
        expected = expected.compose(YGate(), [1])
        expected = expected.compose(Delay(50), [1])

        self.assertEqual(ghz4_dd, expected)
    def test_dd_with_calibrations_with_parameters(self, param_value):
        """Check that calibrations in a circuit with parameters work fine."""

        circ = QuantumCircuit(2)
        circ.x(0)
        circ.cx(0, 1)
        circ.rx(param_value, 1)

        rx_duration = int(param_value * 1000)

        with pulse.build() as rx:
            pulse.play(pulse.Gaussian(rx_duration, 0.1, rx_duration // 4),
                       pulse.DriveChannel(1))

        circ.add_calibration("rx", (1, ), rx, params=[param_value])

        durations = InstructionDurations([("x", None, 100), ("cx", None, 300)])

        dd_sequence = [XGate(), XGate()]
        pm = PassManager([
            ALAPScheduleAnalysis(durations),
            PadDynamicalDecoupling(durations, dd_sequence)
        ])

        self.assertEqual(pm.run(circ).duration, rx_duration + 100 + 300)
예제 #3
0
    def test_scheduling_with_calibration(self):
        """Test if calibrated instruction can update node duration."""
        qc = QuantumCircuit(2)
        qc.x(0)
        qc.cx(0, 1)
        qc.x(1)
        qc.cx(0, 1)

        xsched = Schedule(Play(Constant(300, 0.1), DriveChannel(0)))
        qc.add_calibration("x", (0, ), xsched)

        durations = InstructionDurations([("x", None, 160), ("cx", None, 600)])
        pm = PassManager([ASAPScheduleAnalysis(durations), PadDelay()])
        scheduled = pm.run(qc)

        expected = QuantumCircuit(2)
        expected.x(0)
        expected.delay(300, 1)
        expected.cx(0, 1)
        expected.x(1)
        expected.delay(160, 0)
        expected.cx(0, 1)
        expected.add_calibration("x", (0, ), xsched)

        self.assertEqual(expected, scheduled)
def swap_direction(circuit: DAGCircuit, coupling: CouplingMap):
    if not coupling.is_symmetric:
        cxDirection = [CXDirection(coupling)]
        pass_manager = PassManager(cxDirection)
        transpiled_circuit = pass_manager.run(circuit)
        return transpiled_circuit
    else:
        return circuit
예제 #5
0
    def test_active_reset_circuit(self, write_lat, cond_lat):
        """Test practical example of reset circuit.

        Because of the stimulus pulse overlap with the previous XGate on the q register,
        measure instruction is always triggered after XGate regardless of write latency.
        Thus only conditional latency matters in the scheduling.

        (input)
             ┌─┐   ┌───┐   ┌─┐   ┌───┐   ┌─┐   ┌───┐
          q: ┤M├───┤ X ├───┤M├───┤ X ├───┤M├───┤ X ├───
             └╥┘   └─╥─┘   └╥┘   └─╥─┘   └╥┘   └─╥─┘
              ║ ┌────╨────┐ ║ ┌────╨────┐ ║ ┌────╨────┐
        c: 1/═╩═╡ c_0=0x1 ╞═╩═╡ c_0=0x1 ╞═╩═╡ c_0=0x1 ╞
              0 └─────────┘ 0 └─────────┘ 0 └─────────┘

        """
        qc = QuantumCircuit(1, 1)
        qc.measure(0, 0)
        qc.x(0).c_if(0, 1)
        qc.measure(0, 0)
        qc.x(0).c_if(0, 1)
        qc.measure(0, 0)
        qc.x(0).c_if(0, 1)

        durations = InstructionDurations([("x", None, 100),
                                          ("measure", None, 1000)])

        actual_asap = PassManager([
            SetIOLatency(clbit_write_latency=write_lat,
                         conditional_latency=cond_lat),
            ASAPScheduleAnalysis(durations),
            PadDelay(),
        ]).run(qc)

        actual_alap = PassManager([
            SetIOLatency(clbit_write_latency=write_lat,
                         conditional_latency=cond_lat),
            ALAPScheduleAnalysis(durations),
            PadDelay(),
        ]).run(qc)

        expected = QuantumCircuit(1, 1)
        expected.measure(0, 0)
        if cond_lat > 0:
            expected.delay(cond_lat, 0)
        expected.x(0).c_if(0, 1)
        expected.measure(0, 0)
        if cond_lat > 0:
            expected.delay(cond_lat, 0)
        expected.x(0).c_if(0, 1)
        expected.measure(0, 0)
        if cond_lat > 0:
            expected.delay(cond_lat, 0)
        expected.x(0).c_if(0, 1)

        self.assertEqual(expected, actual_asap)
        self.assertEqual(expected, actual_alap)
    def test_insert_dd_bad_sequence(self):
        """Test DD raises when non-identity sequence is inserted."""
        dd_sequence = [XGate(), YGate()]
        pm = PassManager([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(self.durations, dd_sequence),
        ])

        with self.assertRaises(TranspilerError):
            pm.run(self.ghz4)
def swap(circuit: DAGCircuit, coupling: CouplingMap):
    # embedding is needed for the swap algorithm
    passes = [
        DenseLayout(coupling_map=coupling),
        FullAncillaAllocation(coupling),
        EnlargeWithAncilla(),
        ApplyLayout(),
        LookaheadSwap(coupling_map=coupling)
    ]
    pass_manager = PassManager(passes)
    transpiled_circuit = pass_manager.run(circuit)
    return transpiled_circuit
예제 #8
0
    def test_insert_dd_ghz_one_qubit(self):
        """Test DD gates are inserted on only one qubit.

                      ┌───┐            ┌────────────────┐      ┌───┐       »
           q_0: ──────┤ H ├─────────■──┤ Delay(100[dt]) ├──────┤ X ├───────»
                ┌─────┴───┴─────┐ ┌─┴─┐└────────────────┘┌─────┴───┴──────┐»
           q_1: ┤ Delay(50[dt]) ├─┤ X ├────────■─────────┤ Delay(300[dt]) ├»
                ├───────────────┴┐└───┘      ┌─┴─┐       └────────────────┘»
           q_2: ┤ Delay(750[dt]) ├───────────┤ X ├───────────────■─────────»
                ├────────────────┤           └───┘             ┌─┴─┐       »
           q_3: ┤ Delay(950[dt]) ├─────────────────────────────┤ X ├───────»
                └────────────────┘                             └───┘       »
        meas: 4/═══════════════════════════════════════════════════════════»
                                                                           »
        «        ┌────────────────┐┌───┐┌────────────────┐ ░ ┌─┐
        «   q_0: ┤ Delay(200[dt]) ├┤ X ├┤ Delay(100[dt]) ├─░─┤M├─────────
        «        └────────────────┘└───┘└────────────────┘ ░ └╥┘┌─┐
        «   q_1: ──────────────────────────────────────────░──╫─┤M├──────
        «                                                  ░  ║ └╥┘┌─┐
        «   q_2: ──────────────────────────────────────────░──╫──╫─┤M├───
        «                                                  ░  ║  ║ └╥┘┌─┐
        «   q_3: ──────────────────────────────────────────░──╫──╫──╫─┤M├
        «                                                  ░  ║  ║  ║ └╥┘
        «meas: 4/═════════════════════════════════════════════╩══╩══╩══╩═
        «                                                     0  1  2  3
        """
        dd_sequence = [XGate(), XGate()]
        pm = PassManager(
            [
                ALAPSchedule(self.durations),
                DynamicalDecoupling(self.durations, dd_sequence, qubits=[0]),
            ]
        )

        ghz4_dd = pm.run(self.ghz4.measure_all(inplace=False))

        expected = self.ghz4.copy()
        expected = expected.compose(Delay(50), [1], front=True)
        expected = expected.compose(Delay(750), [2], front=True)
        expected = expected.compose(Delay(950), [3], front=True)

        expected = expected.compose(Delay(100), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(200), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(100), [0])

        expected = expected.compose(Delay(300), [1])

        expected.measure_all()

        self.assertEqual(ghz4_dd, expected)
    def test_insert_midmeas_hahn_asap(self):
        """Test a single X gate as Hahn echo can absorb in the upstream circuit.

                               ┌──────────────────┐ ┌────────────────┐┌─────────┐»
        q_0: ────────■─────────┤ U(3π/4,-π/2,π/2) ├─┤ Delay(600[dt]) ├┤ Rx(π/4) ├»
                   ┌─┴─┐       └──────────────────┘┌┴────────────────┤└─────────┘»
        q_1: ──────┤ X ├────────────────■──────────┤ Delay(1000[dt]) ├─────■─────»
             ┌─────┴───┴──────┐       ┌─┴─┐        └───────┬─┬───────┘   ┌─┴─┐   »
        q_2: ┤ Delay(700[dt]) ├───────┤ X ├────────────────┤M├───────────┤ X ├───»
             └────────────────┘       └───┘                └╥┘           └───┘   »
        c: 1/═══════════════════════════════════════════════╩════════════════════»
                                                            0                    »
        «     ┌────────────────┐
        «q_0: ┤ Delay(600[dt]) ├──■──
        «     └────────────────┘┌─┴─┐
        «q_1: ──────────────────┤ X ├
        «     ┌────────────────┐└───┘
        «q_2: ┤ Delay(700[dt]) ├─────
        «     └────────────────┘
        «c: 1/═══════════════════════
        «
        """
        dd_sequence = [RXGate(pi / 4)]
        pm = PassManager([
            ASAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(self.durations, dd_sequence),
        ])

        midmeas_dd = pm.run(self.midmeas)

        combined_u = UGate(3 * pi / 4, -pi / 2, pi / 2)

        expected = QuantumCircuit(3, 1)
        expected.cx(0, 1)
        expected.compose(combined_u, [0], inplace=True)
        expected.delay(600, 0)
        expected.rx(pi / 4, 0)
        expected.delay(600, 0)
        expected.delay(700, 2)
        expected.cx(1, 2)
        expected.delay(1000, 1)
        expected.measure(2, 0)
        expected.cx(1, 2)
        expected.cx(0, 1)
        expected.delay(700, 2)

        self.assertEqual(midmeas_dd, expected)
        # check the absorption into U was done correctly
        self.assertTrue(
            Operator(XGate()).equiv(
                Operator(UGate(3 * pi / 4, -pi / 2, pi / 2))
                & Operator(RXGate(pi / 4))))
    def test_insert_midmeas_hahn_alap(self):
        """Test a single X gate as Hahn echo can absorb in the downstream circuit.

        global phase: 3π/2
                               ┌────────────────┐       ┌───┐       ┌────────────────┐»
        q_0: ────────■─────────┤ Delay(625[dt]) ├───────┤ X ├───────┤ Delay(625[dt]) ├»
                   ┌─┴─┐       └────────────────┘┌──────┴───┴──────┐└────────────────┘»
        q_1: ──────┤ X ├───────────────■─────────┤ Delay(1000[dt]) ├────────■─────────»
             ┌─────┴───┴──────┐      ┌─┴─┐       └───────┬─┬───────┘      ┌─┴─┐       »
        q_2: ┤ Delay(700[dt]) ├──────┤ X ├───────────────┤M├──────────────┤ X ├───────»
             └────────────────┘      └───┘               └╥┘              └───┘       »
        c: 1/═════════════════════════════════════════════╩═══════════════════════════»
                                                          0                           »
        «     ┌───────────────┐
        «q_0: ┤ U(0,π/2,-π/2) ├───■──
        «     └───────────────┘ ┌─┴─┐
        «q_1: ──────────────────┤ X ├
        «     ┌────────────────┐└───┘
        «q_2: ┤ Delay(700[dt]) ├─────
        «     └────────────────┘
        «c: 1/═══════════════════════
        """
        dd_sequence = [XGate()]
        pm = PassManager([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(self.durations, dd_sequence),
        ])

        midmeas_dd = pm.run(self.midmeas)

        combined_u = UGate(0, pi / 2, -pi / 2)

        expected = QuantumCircuit(3, 1)
        expected.cx(0, 1)
        expected.delay(625, 0)
        expected.x(0)
        expected.delay(625, 0)
        expected.compose(combined_u, [0], inplace=True)
        expected.delay(700, 2)
        expected.cx(1, 2)
        expected.delay(1000, 1)
        expected.measure(2, 0)
        expected.cx(1, 2)
        expected.cx(0, 1)
        expected.delay(700, 2)
        expected.global_phase = 4.71238898038469

        self.assertEqual(midmeas_dd, expected)
        # check the absorption into U was done correctly
        self.assertEqual(Operator(combined_u),
                         Operator(XGate()) & Operator(XGate()))
예제 #11
0
def default_pass_manager_simulator(basis_gates):
    """
    The default pass manager without a coupling map.

    Args:
        basis_gates (list[str]): list of basis gate names to unroll to.

    Returns:
        PassManager: A passmanager that just unrolls, without any optimization.
    """
    pass_manager = PassManager()
    pass_manager.append(Unroller(basis_gates))

    return pass_manager
예제 #12
0
def generate_pre_op_passmanager(target=None,
                                coupling_map=None,
                                remove_reset_in_zero=False):
    """Generate a pre-optimization loop :class:`~qiskit.transpiler.PassManager`

    This pass manager will check to ensure that directionality from the coupling
    map is respected

    Args:
        target (Target): the :class:`~.Target` object representing the backend
        coupling_map (CouplingMap): The coupling map to use
        remove_reset_in_zero (bool): If ``True`` include the remove reset in
            zero pass in the generated PassManager
    Returns:
        PassManager: The pass manager

    """
    pre_opt = PassManager()
    if coupling_map:
        pre_opt.append(CheckGateDirection(coupling_map, target=target))

        def _direction_condition(property_set):
            return not property_set["is_direction_mapped"]

        pre_opt.append([GateDirection(coupling_map, target=target)],
                       condition=_direction_condition)
    if remove_reset_in_zero:
        pre_opt.append(RemoveResetInZeroState())
    return pre_opt
예제 #13
0
 def unroll_and_map_circuit(self, circuit: QuantumCircuit, mapping,
                            backend) -> QuantumCircuit:
     layout = Layout({q: i for q, i in zip(circuit.qubits, mapping)})
     pm = PassManager([
         SetLayout(layout),
         ApplyLayout(),
         Unroller(self._backend.configuration().basis_gates),
     ])
     # pm = level_0_pass_manager(PassManagerConfig(
     #     initial_layout = layout,
     #     basis_gates=backend.configuration().basis_gates,
     #     coupling_map=CouplingMap(backend.configuration().coupling_map),
     #     backend_properties=backend.properties()
     # ))
     return pm.run(circuit)
    def test_insert_dd_ghz(self):
        """Test DD gates are inserted in correct spots.

                   ┌───┐            ┌────────────────┐      ┌───┐      »
        q_0: ──────┤ H ├─────────■──┤ Delay(100[dt]) ├──────┤ X ├──────»
             ┌─────┴───┴─────┐ ┌─┴─┐└────────────────┘┌─────┴───┴─────┐»
        q_1: ┤ Delay(50[dt]) ├─┤ X ├────────■─────────┤ Delay(50[dt]) ├»
             ├───────────────┴┐└───┘      ┌─┴─┐       └───────────────┘»
        q_2: ┤ Delay(750[dt]) ├───────────┤ X ├───────────────■────────»
             ├────────────────┤           └───┘             ┌─┴─┐      »
        q_3: ┤ Delay(950[dt]) ├─────────────────────────────┤ X ├──────»
             └────────────────┘                             └───┘      »
        «     ┌────────────────┐      ┌───┐       ┌────────────────┐
        «q_0: ┤ Delay(200[dt]) ├──────┤ X ├───────┤ Delay(100[dt]) ├─────────────────
        «     └─────┬───┬──────┘┌─────┴───┴──────┐└─────┬───┬──────┘┌───────────────┐
        «q_1: ──────┤ X ├───────┤ Delay(100[dt]) ├──────┤ X ├───────┤ Delay(50[dt]) ├
        «           └───┘       └────────────────┘      └───┘       └───────────────┘
        «q_2: ───────────────────────────────────────────────────────────────────────
        «
        «q_3: ───────────────────────────────────────────────────────────────────────
        «
        """
        dd_sequence = [XGate(), XGate()]
        pm = PassManager([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(self.durations, dd_sequence),
        ])

        ghz4_dd = pm.run(self.ghz4)

        expected = self.ghz4.copy()
        expected = expected.compose(Delay(50), [1], front=True)
        expected = expected.compose(Delay(750), [2], front=True)
        expected = expected.compose(Delay(950), [3], front=True)

        expected = expected.compose(Delay(100), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(200), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(100), [0])

        expected = expected.compose(Delay(50), [1])
        expected = expected.compose(XGate(), [1])
        expected = expected.compose(Delay(100), [1])
        expected = expected.compose(XGate(), [1])
        expected = expected.compose(Delay(50), [1])

        self.assertEqual(ghz4_dd, expected)
예제 #15
0
    def test_no_pad_very_end_of_circuit(self):
        """Test padding option that inserts no delay at the very end of circuit.

        This circuit will be unchanged after ASAP-schedule/padding.

             ┌────────────────┐┌─┐
        q_0: ┤ Delay(100[dt]) ├┤M├
             └─────┬───┬──────┘└╥┘
        q_1: ──────┤ X ├────────╫─
                   └───┘        ║
        c: 1/═══════════════════╩═
                                0
        """
        qc = QuantumCircuit(2, 1)
        qc.delay(100, 0)
        qc.x(1)
        qc.measure(0, 0)

        durations = InstructionDurations([("x", None, 160),
                                          ("measure", None, 1000)])

        scheduled = PassManager([
            ASAPScheduleAnalysis(durations),
            PadDelay(fill_very_end=False),
        ]).run(qc)

        self.assertEqual(scheduled, qc)
예제 #16
0
    def test_c_if_on_different_qubits(self, schedule_pass):
        """Test if ALAP/ASAP schedules circuits with `c_if`s on different qubits.

        (input)
             ┌─┐
        q_0: ┤M├──────────────────────
             └╥┘   ┌───┐
        q_1: ─╫────┤ X ├──────────────
              ║    └─╥─┘      ┌───┐
        q_2: ─╫──────╫────────┤ X ├───
              ║      ║        └─╥─┘
              ║ ┌────╨────┐┌────╨────┐
        c: 1/═╩═╡ c_0 = T ╞╡ c_0 = T ╞
              0 └─────────┘└─────────┘

        (scheduled)

                                ┌─┐┌────────────────┐
        q_0: ───────────────────┤M├┤ Delay(200[dt]) ├───────────
             ┌─────────────────┐└╥┘└─────┬───┬──────┘
        q_1: ┤ Delay(1000[dt]) ├─╫───────┤ X ├──────────────────
             ├─────────────────┤ ║       └─╥─┘          ┌───┐
        q_2: ┤ Delay(1000[dt]) ├─╫─────────╫────────────┤ X ├───
             └─────────────────┘ ║         ║            └─╥─┘
                                 ║    ┌────╨────┐    ┌────╨────┐
        c: 1/════════════════════╩════╡ c_0=0x1 ╞════╡ c_0=0x1 ╞
                                 0    └─────────┘    └─────────┘
        """
        qc = QuantumCircuit(3, 1)
        qc.measure(0, 0)
        qc.x(1).c_if(0, True)
        qc.x(2).c_if(0, True)

        durations = InstructionDurations([("x", None, 200),
                                          ("measure", None, 1000)])
        pm = PassManager([schedule_pass(durations), PadDelay()])
        scheduled = pm.run(qc)

        expected = QuantumCircuit(3, 1)
        expected.measure(0, 0)
        expected.delay(1000, 1)
        expected.delay(1000, 2)
        expected.x(1).c_if(0, True)
        expected.x(2).c_if(0, True)
        expected.delay(200, 0)

        self.assertEqual(expected, scheduled)
예제 #17
0
    def test_dag_introduces_extra_dependency_between_conditionals(self):
        """Test dependency between conditional operations in the scheduling.

        In the below example circuit, the conditional x on q1 could start at time 0,
        however it must be scheduled after the conditional x on q0 in ASAP scheduling.
        That is because circuit model used in the transpiler passes (DAGCircuit)
        interprets instructions acting on common clbits must be run in the order
        given by the original circuit (QuantumCircuit).

        (input)
             ┌────────────────┐   ┌───┐
        q_0: ┤ Delay(100[dt]) ├───┤ X ├───
             └─────┬───┬──────┘   └─╥─┘
        q_1: ──────┤ X ├────────────╫─────
                   └─╥─┘            ║
                ┌────╨────┐    ┌────╨────┐
        c: 1/═══╡ c_0=0x1 ╞════╡ c_0=0x1 ╞
                └─────────┘    └─────────┘

        (ASAP scheduled)
             ┌────────────────┐   ┌───┐
        q_0: ┤ Delay(100[dt]) ├───┤ X ├──────────────
             ├────────────────┤   └─╥─┘      ┌───┐
        q_1: ┤ Delay(100[dt]) ├─────╫────────┤ X ├───
             └────────────────┘     ║        └─╥─┘
                               ┌────╨────┐┌────╨────┐
        c: 1/══════════════════╡ c_0=0x1 ╞╡ c_0=0x1 ╞
                               └─────────┘└─────────┘
        """
        qc = QuantumCircuit(2, 1)
        qc.delay(100, 0)
        qc.x(0).c_if(0, True)
        qc.x(1).c_if(0, True)

        durations = InstructionDurations([("x", None, 160)])
        pm = PassManager([ASAPScheduleAnalysis(durations), PadDelay()])
        scheduled = pm.run(qc)

        expected = QuantumCircuit(2, 1)
        expected.delay(100, 0)
        expected.delay(100, 1)  # due to extra dependency on clbits
        expected.x(0).c_if(0, True)
        expected.x(1).c_if(0, True)

        self.assertEqual(expected, scheduled)
예제 #18
0
    def test_measure_after_c_if(self, schedule_pass):
        """Test if ALAP/ASAP schedules circuits with c_if after measure with a common clbit.

        (input)
             ┌─┐
        q_0: ┤M├──────────────
             └╥┘   ┌───┐
        q_1: ─╫────┤ X ├──────
              ║    └─╥─┘   ┌─┐
        q_2: ─╫──────╫─────┤M├
              ║ ┌────╨────┐└╥┘
        c: 1/═╩═╡ c_0 = T ╞═╩═
              0 └─────────┘ 0

        (scheduled)
                                ┌─┐┌─────────────────┐
        q_0: ───────────────────┤M├┤ Delay(1000[dt]) ├──────────────────
             ┌─────────────────┐└╥┘└──────┬───┬──────┘┌────────────────┐
        q_1: ┤ Delay(1000[dt]) ├─╫────────┤ X ├───────┤ Delay(800[dt]) ├
             ├─────────────────┤ ║        └─╥─┘       └──────┬─┬───────┘
        q_2: ┤ Delay(1000[dt]) ├─╫──────────╫────────────────┤M├────────
             └─────────────────┘ ║     ┌────╨────┐           └╥┘
        c: 1/════════════════════╩═════╡ c_0=0x1 ╞════════════╩═════════
                                 0     └─────────┘            0
        """
        qc = QuantumCircuit(3, 1)
        qc.measure(0, 0)
        qc.x(1).c_if(0, 1)
        qc.measure(2, 0)

        durations = InstructionDurations([("x", None, 200),
                                          ("measure", None, 1000)])
        pm = PassManager([schedule_pass(durations), PadDelay()])
        scheduled = pm.run(qc)

        expected = QuantumCircuit(3, 1)
        expected.delay(1000, 1)
        expected.delay(1000, 2)
        expected.measure(0, 0)
        expected.x(1).c_if(0, 1)
        expected.measure(2, 0)
        expected.delay(1000, 0)
        expected.delay(800, 1)

        self.assertEqual(expected, scheduled)
예제 #19
0
    def test_padding_not_working_without_scheduling(self):
        """Test padding fails when un-scheduled DAG is input."""
        qc = QuantumCircuit(1, 1)
        qc.delay(100, 0)
        qc.x(0)
        qc.measure(0, 0)

        with self.assertRaises(TranspilerError):
            PassManager(PadDelay()).run(qc)
예제 #20
0
    def setUp(self):
        coupling = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]
        coupling_map = CouplingMap(couplinglist=coupling)
        basis_gates = ['u1', 'u3', 'u2', 'cx']
        qr = QuantumRegister(7, 'q')
        layout = Layout({qr[i]: i for i in range(coupling_map.size())})

        # Create a pass manager with a variety of passes and flow control structures
        self.pass_manager = PassManager()
        self.pass_manager.append(SetLayout(layout))
        self.pass_manager.append(TrivialLayout(coupling_map), condition=lambda x: True)
        self.pass_manager.append(FullAncillaAllocation(coupling_map))
        self.pass_manager.append(EnlargeWithAncilla())
        self.pass_manager.append(Unroller(basis_gates))
        self.pass_manager.append(CheckMap(coupling_map))
        self.pass_manager.append(BarrierBeforeFinalMeasurements(), do_while=lambda x: False)
        self.pass_manager.append(CXDirection(coupling_map))
        self.pass_manager.append(RemoveResetInZeroState())
    def test_asymmetric_xy4_in_t2(self):
        """Test insertion of XY4 sequence with unbalanced spacing.

        global phase: π
             ┌───┐┌───┐┌────────────────┐┌───┐┌────────────────┐┌───┐┌────────────────┐»
        q_0: ┤ H ├┤ X ├┤ Delay(450[dt]) ├┤ Y ├┤ Delay(450[dt]) ├┤ X ├┤ Delay(450[dt]) ├»
             └───┘└───┘└────────────────┘└───┘└────────────────┘└───┘└────────────────┘»
        «     ┌───┐┌────────────────┐┌───┐
        «q_0: ┤ Y ├┤ Delay(450[dt]) ├┤ H ├
        «     └───┘└────────────────┘└───┘
        """
        dd_sequence = [XGate(), YGate()] * 2
        spacing = [0] + [1 / 4] * 4
        pm = PassManager([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(self.durations,
                                   dd_sequence,
                                   spacing=spacing),
        ])

        t2 = QuantumCircuit(1)
        t2.h(0)
        t2.delay(2000, 0)
        t2.h(0)

        expected = QuantumCircuit(1)
        expected.h(0)
        expected.x(0)
        expected.delay(450, 0)
        expected.y(0)
        expected.delay(450, 0)
        expected.x(0)
        expected.delay(450, 0)
        expected.y(0)
        expected.delay(450, 0)
        expected.h(0)
        expected.global_phase = pi

        t2_dd = pm.run(t2)

        self.assertEqual(t2_dd, expected)
        # check global phase is correct
        self.assertEqual(Operator(t2), Operator(expected))
예제 #22
0
    def test_dd_after_reset(self):
        """Test skip_reset_qubits option works.

                  ┌─────────────────┐┌───┐┌────────────────┐┌───┐┌─────────────────┐»
        q_0: ─|0>─┤ Delay(1000[dt]) ├┤ H ├┤ Delay(190[dt]) ├┤ X ├┤ Delay(1710[dt]) ├»
                  └─────────────────┘└───┘└────────────────┘└───┘└─────────────────┘»
        «     ┌───┐┌───┐
        «q_0: ┤ X ├┤ H ├
        «     └───┘└───┘
        """
        dd_sequence = [XGate(), XGate()]
        spacing = [0.1, 0.9]
        pm = PassManager(
            [
                ALAPSchedule(self.durations),
                DynamicalDecoupling(
                    self.durations, dd_sequence, spacing=spacing, skip_reset_qubits=True
                ),
            ]
        )

        t2 = QuantumCircuit(1)
        t2.reset(0)
        t2.delay(1000)
        t2.h(0)
        t2.delay(2000, 0)
        t2.h(0)

        expected = QuantumCircuit(1)
        expected.reset(0)
        expected.delay(1000)
        expected.h(0)
        expected.delay(190, 0)
        expected.x(0)
        expected.delay(1710, 0)
        expected.x(0)
        expected.h(0)

        t2_dd = pm.run(t2)

        self.assertEqual(t2_dd, expected)
예제 #23
0
    def test_measure_after_measure(self, schedule_pass):
        """Test if ALAP/ASAP schedules circuits with measure after measure with a common clbit.
        See: https://github.com/Qiskit/qiskit-terra/issues/7006

        (input)
             ┌───┐┌─┐
        q_0: ┤ X ├┤M├───
             └───┘└╥┘┌─┐
        q_1: ──────╫─┤M├
                   ║ └╥┘
        c: 1/══════╩══╩═
                   0  0

        (scheduled)
                   ┌───┐       ┌─┐
        q_0: ──────┤ X ├───────┤M├───
             ┌─────┴───┴──────┐└╥┘┌─┐
        q_1: ┤ Delay(200[dt]) ├─╫─┤M├
             └────────────────┘ ║ └╥┘
        c: 1/═══════════════════╩══╩═
                                0  0
        """
        qc = QuantumCircuit(2, 1)
        qc.x(0)
        qc.measure(0, 0)
        qc.measure(1, 0)

        durations = InstructionDurations([("x", None, 200),
                                          ("measure", None, 1000)])
        pm = PassManager(schedule_pass(durations))
        scheduled = pm.run(qc)

        expected = QuantumCircuit(2, 1)
        expected.x(0)
        expected.measure(0, 0)
        expected.delay(
            200,
            1)  # 2nd measure starts at the same time as 1st measure starts
        expected.measure(1, 0)

        self.assertEqual(expected, scheduled)
예제 #24
0
    def _layout_and_route_passmanager(self, initial_layout):
        """Return a passmanager for a full layout and routing.

        We use a factory to remove potential statefulness of passes.
        """
        layout_and_route = [SetLayout(initial_layout),
                            FullAncillaAllocation(self.coupling_map),
                            EnlargeWithAncilla(),
                            ApplyLayout(),
                            self.routing_pass]
        pm = PassManager(layout_and_route)
        return pm
예제 #25
0
    def test_classically_controlled_gate_after_measure(self, schedule_pass):
        """Test if ALAP/ASAP schedules circuits with c_if after measure with a common clbit.
        See: https://github.com/Qiskit/qiskit-terra/issues/7006

        (input)
             ┌─┐
        q_0: ┤M├───────────
             └╥┘   ┌───┐
        q_1: ─╫────┤ X ├───
              ║    └─╥─┘
              ║ ┌────╨────┐
        c: 1/═╩═╡ c_0 = T ╞
              0 └─────────┘

        (scheduled)
                                ┌─┐┌────────────────┐
        q_0: ───────────────────┤M├┤ Delay(200[dt]) ├
             ┌─────────────────┐└╥┘└─────┬───┬──────┘
        q_1: ┤ Delay(1000[dt]) ├─╫───────┤ X ├───────
             └─────────────────┘ ║       └─╥─┘
                                 ║    ┌────╨────┐
        c: 1/════════════════════╩════╡ c_0 = T ╞════
                                 0    └─────────┘
        """
        qc = QuantumCircuit(2, 1)
        qc.measure(0, 0)
        qc.x(1).c_if(0, True)

        durations = InstructionDurations([("x", None, 200),
                                          ("measure", None, 1000)])
        pm = PassManager(schedule_pass(durations))
        scheduled = pm.run(qc)

        expected = QuantumCircuit(2, 1)
        expected.measure(0, 0)
        expected.delay(200, 0)
        expected.delay(1000, 1)  # x.c_if starts after measure
        expected.x(1).c_if(0, True)

        self.assertEqual(expected, scheduled)
예제 #26
0
    def test_shorter_measure_after_measure(self, schedule_pass):
        """Test if ALAP/ASAP schedules circuits with shorter measure after measure with a common clbit.

        (input)
             ┌─┐
        q_0: ┤M├───
             └╥┘┌─┐
        q_1: ─╫─┤M├
              ║ └╥┘
        c: 1/═╩══╩═
              0  0

        (scheduled)
                                ┌─┐┌────────────────┐
        q_0: ───────────────────┤M├┤ Delay(700[dt]) ├
             ┌─────────────────┐└╥┘└──────┬─┬───────┘
        q_1: ┤ Delay(1000[dt]) ├─╫────────┤M├────────
             └─────────────────┘ ║        └╥┘
        c: 1/════════════════════╩═════════╩═════════
                                 0         0
        """
        qc = QuantumCircuit(2, 1)
        qc.measure(0, 0)
        qc.measure(1, 0)

        durations = InstructionDurations([("measure", [0], 1000),
                                          ("measure", [1], 700)])
        pm = PassManager([schedule_pass(durations), PadDelay()])
        scheduled = pm.run(qc)

        expected = QuantumCircuit(2, 1)
        expected.measure(0, 0)
        expected.delay(1000, 1)
        expected.measure(1, 0)
        expected.delay(700, 0)

        self.assertEqual(expected, scheduled)
예제 #27
0
def generate_embed_passmanager(coupling_map):
    """Generate a layout embedding :class:`~qiskit.transpiler.PassManager`

    This is used to generate a :class:`~qiskit.transpiler.PassManager` object
    that can be used to expand and apply an initial layout to a circuit

    Args:
        coupling_map (CouplingMap): The coupling map for the backend to embed
            the circuit to.
    Returns:
        PassManager: The embedding passmanager that assumes the layout property
            set has been set in earlier stages
    """
    return PassManager([
        FullAncillaAllocation(coupling_map),
        EnlargeWithAncilla(),
        ApplyLayout()
    ])
예제 #28
0
def generate_unroll_3q(
    target,
    basis_gates=None,
    approximation_degree=None,
    unitary_synthesis_method="default",
    unitary_synthesis_plugin_config=None,
):
    """Generate an unroll >3q :class:`~qiskit.transpiler.PassManager`

    Args:
        target (Target): the :class:`~.Target` object representing the backend
        basis_gates (list): A list of str gate names that represent the basis
            gates on the backend target
        approximation_degree (float): The heuristic approximation degree to
            use. Can be between 0 and 1.
        unitary_synthesis_method (str): The unitary synthesis method to use
        unitary_synthesis_plugin_config (dict): The optional dictionary plugin
            configuration, this is plugin specific refer to the specified plugin's
            documenation for how to use.

    Returns:
        PassManager: The unroll 3q or more pass manager
    """
    unroll_3q = PassManager()
    unroll_3q.append(
        UnitarySynthesis(
            basis_gates,
            approximation_degree=approximation_degree,
            method=unitary_synthesis_method,
            min_qubits=3,
            plugin_config=unitary_synthesis_plugin_config,
            target=target,
        ))
    unroll_3q.append(HighLevelSynthesis())
    unroll_3q.append(Unroll3qOrMore(target=target, basis_gates=basis_gates))
    return unroll_3q
예제 #29
0
    def test_alap_agree_with_reverse_asap_reverse(self):
        """Test if ALAP schedule agrees with doubly-reversed ASAP schedule."""
        qc = QuantumCircuit(2)
        qc.h(0)
        qc.delay(500, 1)
        qc.cx(0, 1)
        qc.measure_all()

        durations = InstructionDurations([("h", 0, 200), ("cx", [0, 1], 700),
                                          ("measure", None, 1000)])

        pm = PassManager(ALAPSchedule(durations))
        alap_qc = pm.run(qc)

        pm = PassManager(ASAPSchedule(durations))
        new_qc = pm.run(qc.reverse_ops())
        new_qc = new_qc.reverse_ops()  # pylint: disable=no-member
        new_qc.name = new_qc.name

        self.assertEqual(alap_qc, new_qc)
예제 #30
0
def default_pass_manager_simulator(basis_gates):
    """
    The default pass manager without a coupling map.

    Args:
        basis_gates (list[str]): list of basis gate names to unroll to.

    Returns:
        PassManager: A passmanager that just unrolls, without any optimization.
    """
    pass_manager = PassManager()

    pass_manager.append(Unroller(basis_gates))

    pass_manager.append(
        [RemoveResetInZeroState(),
         Depth(), FixedPoint('depth')],
        do_while=lambda property_set: not property_set['depth_fixed_point'])

    return pass_manager