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)
    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)
Esempio n. 3
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)
Esempio n. 5
0
    def test_hanh_echo_experiment_type(self):
        """Test Hahn echo experiment type circuit.

        (input)

             ┌────┐┌────────────────┐┌───┐┌────────────────┐┌────┐┌─┐
        q_0: ┤ √X ├┤ Delay(100[dt]) ├┤ X ├┤ Delay(100[dt]) ├┤ √X ├┤M├
             └────┘└────────────────┘└───┘└────────────────┘└────┘└╥┘
        c: 1/══════════════════════════════════════════════════════╩═
                                                                   0

        (output)

             ┌────┐┌────────────────┐┌───┐┌────────────────┐┌────┐┌──────────────┐┌─┐
        q_0: ┤ √X ├┤ Delay(100[dt]) ├┤ X ├┤ Delay(100[dt]) ├┤ √X ├┤ Delay(8[dt]) ├┤M├
             └────┘└────────────────┘└───┘└────────────────┘└────┘└──────────────┘└╥┘
        c: 1/══════════════════════════════════════════════════════════════════════╩═
                                                                                   0

        This type of experiment doesn't change duration of interest (two in the middle).
        However induces slight delay less than alignment * dt before measurement.
        This might induce extra amplitude damping error.
        """
        circuit = QuantumCircuit(1, 1)
        circuit.sx(0)
        circuit.delay(100, 0, unit="dt")
        circuit.x(0)
        circuit.delay(100, 0, unit="dt")
        circuit.sx(0)
        circuit.measure(0, 0)

        pm = PassManager([
            # reproduce old behavior of 0.20.0 before #7655
            # currently default write latency is 0
            SetIOLatency(clbit_write_latency=1600, conditional_latency=0),
            ALAPScheduleAnalysis(durations=self.instruction_durations),
            ConstrainedReschedule(acquire_alignment=16),
            PadDelay(),
        ])

        aligned_circuit = pm.run(circuit)

        ref_circuit = QuantumCircuit(1, 1)
        ref_circuit.sx(0)
        ref_circuit.delay(100, 0, unit="dt")
        ref_circuit.x(0)
        ref_circuit.delay(100, 0, unit="dt")
        ref_circuit.sx(0)
        ref_circuit.delay(8, 0, unit="dt")
        ref_circuit.measure(0, 0)

        self.assertEqual(aligned_circuit, ref_circuit)
Esempio n. 6
0
    def test_mid_circuit_measure(self):
        """Test circuit with mid circuit measurement.

        (input)

             ┌───┐┌────────────────┐┌─┐┌───────────────┐┌───┐┌────────────────┐┌─┐
        q_0: ┤ X ├┤ Delay(100[dt]) ├┤M├┤ Delay(10[dt]) ├┤ X ├┤ Delay(120[dt]) ├┤M├
             └───┘└────────────────┘└╥┘└───────────────┘└───┘└────────────────┘└╥┘
        c: 2/════════════════════════╩══════════════════════════════════════════╩═
                                     0                                          1

        (output)

             ┌───┐┌────────────────┐┌─┐┌───────────────┐┌───┐┌────────────────┐┌─┐
        q_0: ┤ X ├┤ Delay(112[dt]) ├┤M├┤ Delay(10[dt]) ├┤ X ├┤ Delay(134[dt]) ├┤M├
             └───┘└────────────────┘└╥┘└───────────────┘└───┘└────────────────┘└╥┘
        c: 2/════════════════════════╩══════════════════════════════════════════╩═
                                     0                                          1

        Extra delay is always added to the existing delay right before the measurement.
        Delay after measurement is unchanged.
        """
        circuit = QuantumCircuit(1, 2)
        circuit.x(0)
        circuit.delay(100, 0, unit="dt")
        circuit.measure(0, 0)
        circuit.delay(10, 0, unit="dt")
        circuit.x(0)
        circuit.delay(120, 0, unit="dt")
        circuit.measure(0, 1)

        pm = PassManager([
            # reproduce old behavior of 0.20.0 before #7655
            # currently default write latency is 0
            SetIOLatency(clbit_write_latency=1600, conditional_latency=0),
            ALAPScheduleAnalysis(durations=self.instruction_durations),
            ConstrainedReschedule(acquire_alignment=16),
            PadDelay(),
        ])

        aligned_circuit = pm.run(circuit)

        ref_circuit = QuantumCircuit(1, 2)
        ref_circuit.x(0)
        ref_circuit.delay(112, 0, unit="dt")
        ref_circuit.measure(0, 0)
        ref_circuit.delay(10, 0, unit="dt")
        ref_circuit.x(0)
        ref_circuit.delay(134, 0, unit="dt")
        ref_circuit.measure(0, 1)

        self.assertEqual(aligned_circuit, ref_circuit)
    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()))
    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([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(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_dd_can_sequentially_called(self):
        """Test if sequentially called DD pass can output the same circuit.

        This test verifies:
        - if global phase is properly propagated from the previous padding node.
        - if node_start_time property is properly updated for new dag circuit.
        """
        dd_sequence = [XGate(), YGate(), XGate(), YGate()]

        pm1 = PassManager([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(self.durations, dd_sequence, qubits=[0]),
            PadDynamicalDecoupling(self.durations, dd_sequence, qubits=[1]),
        ])
        circ1 = pm1.run(self.ghz4)

        pm2 = PassManager([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(self.durations, dd_sequence, qubits=[0, 1]),
        ])
        circ2 = pm2.run(self.ghz4)

        self.assertEqual(circ1, circ2)
    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)
Esempio n. 11
0
    def test_t1_experiment_type(self):
        """Test T1 experiment type circuit.

        (input)

             ┌───┐┌────────────────┐┌─┐
        q_0: ┤ X ├┤ Delay(100[dt]) ├┤M├
             └───┘└────────────────┘└╥┘
        c: 1/════════════════════════╩═
                                     0

        (aligned)

             ┌───┐┌────────────────┐┌─┐
        q_0: ┤ X ├┤ Delay(112[dt]) ├┤M├
             └───┘└────────────────┘└╥┘
        c: 1/════════════════════════╩═
                                     0

        This type of experiment slightly changes delay duration of interest.
        However the quantization error should be less than alignment * dt.
        """
        circuit = QuantumCircuit(1, 1)
        circuit.x(0)
        circuit.delay(100, 0, unit="dt")
        circuit.measure(0, 0)

        pm = PassManager([
            # reproduce old behavior of 0.20.0 before #7655
            # currently default write latency is 0
            SetIOLatency(clbit_write_latency=1600, conditional_latency=0),
            ALAPScheduleAnalysis(durations=self.instruction_durations),
            ConstrainedReschedule(acquire_alignment=16),
            PadDelay(),
        ])

        aligned_circuit = pm.run(circuit)

        ref_circuit = QuantumCircuit(1, 1)
        ref_circuit.x(0)
        ref_circuit.delay(112, 0, unit="dt")
        ref_circuit.measure(0, 0)

        self.assertEqual(aligned_circuit, ref_circuit)
    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))
Esempio n. 13
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([ALAPScheduleAnalysis(durations), PadDelay()])
        alap_qc = pm.run(qc)

        pm = PassManager([ASAPScheduleAnalysis(durations), PadDelay()])
        new_qc = pm.run(qc.reverse_ops())
        new_qc = new_qc.reverse_ops()
        new_qc.name = new_qc.name

        self.assertEqual(alap_qc, new_qc)
    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([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(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)
Esempio n. 15
0
    def test_both_pulse_and_acquire_alignment(self):
        """Test when both acquire and pulse alignment are specified.

        (input)
             ┌────────────────┐┌───┐┌───────────────┐┌─┐
          q: ┤ Delay(100[dt]) ├┤ X ├┤ Delay(10[dt]) ├┤M├
             └────────────────┘└───┘└───────────────┘└╥┘
        c: 1/═════════════════════════════════════════╩═
                                                      0

        (aligned)
             ┌────────────────┐┌───┐┌───────────────┐┌─┐
          q: ┤ Delay(112[dt]) ├┤ X ├┤ Delay(16[dt]) ├┤M├
             └────────────────┘└───┘└───────────────┘└╥┘
        c: 1/═════════════════════════════════════════╩═
                                                      0
        """
        pm = PassManager([
            ALAPScheduleAnalysis(durations=self.instruction_durations),
            ConstrainedReschedule(pulse_alignment=16, acquire_alignment=16),
            PadDelay(fill_very_end=False),
        ])

        circuit = QuantumCircuit(1, 1)
        circuit.delay(100, 0, unit="dt")
        circuit.x(0)
        circuit.delay(10, 0, unit="dt")
        circuit.measure(0, 0)

        ref_circ = QuantumCircuit(1, 1)
        ref_circ.delay(112, 0, unit="dt")
        ref_circ.x(0)
        ref_circ.delay(16, 0, unit="dt")
        ref_circ.measure(0, 0)

        self.assertEqual(pm.run(circuit), ref_circ)
    def test_insert_dd_ghz_xy4_with_alignment(self):
        """Test DD with pulse alignment constraints.

                   ┌───┐            ┌───────────────┐      ┌───┐      ┌───────────────┐»
        q_0: ──────┤ H ├─────────■──┤ Delay(40[dt]) ├──────┤ X ├──────┤ Delay(70[dt]) ├»
             ┌─────┴───┴─────┐ ┌─┴─┐└───────────────┘┌─────┴───┴─────┐└─────┬───┬─────┘»
        q_1: ┤ Delay(50[dt]) ├─┤ X ├────────■────────┤ Delay(20[dt]) ├──────┤ X ├──────»
             ├───────────────┴┐└───┘      ┌─┴─┐      └───────────────┘      └───┘      »
        q_2: ┤ Delay(750[dt]) ├───────────┤ X ├──────────────■─────────────────────────»
             ├────────────────┤           └───┘            ┌─┴─┐                       »
        q_3: ┤ Delay(950[dt]) ├────────────────────────────┤ X ├───────────────────────»
             └────────────────┘                            └───┘                       »
        «           ┌───┐      ┌───────────────┐      ┌───┐      ┌───────────────┐»
        «q_0: ──────┤ Y ├──────┤ Delay(70[dt]) ├──────┤ X ├──────┤ Delay(70[dt]) ├»
        «     ┌─────┴───┴─────┐└─────┬───┬─────┘┌─────┴───┴─────┐└─────┬───┬─────┘»
        «q_1: ┤ Delay(20[dt]) ├──────┤ Y ├──────┤ Delay(20[dt]) ├──────┤ X ├──────»
        «     └───────────────┘      └───┘      └───────────────┘      └───┘      »
        «q_2: ────────────────────────────────────────────────────────────────────»
        «                                                                         »
        «q_3: ────────────────────────────────────────────────────────────────────»
        «                                                                         »
        «           ┌───┐      ┌───────────────┐
        «q_0: ──────┤ Y ├──────┤ Delay(50[dt]) ├─────────────────
        «     ┌─────┴───┴─────┐└─────┬───┬─────┘┌───────────────┐
        «q_1: ┤ Delay(20[dt]) ├──────┤ Y ├──────┤ Delay(20[dt]) ├
        «     └───────────────┘      └───┘      └───────────────┘
        «q_2: ───────────────────────────────────────────────────
        «
        «q_3: ───────────────────────────────────────────────────
        «
        """
        dd_sequence = [XGate(), YGate(), XGate(), YGate()]
        pm = PassManager([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(
                self.durations,
                dd_sequence,
                pulse_alignment=10,
                extra_slack_distribution="edges",
            ),
        ])

        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(40), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(70), [0])
        expected = expected.compose(YGate(), [0])
        expected = expected.compose(Delay(70), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(70), [0])
        expected = expected.compose(YGate(), [0])
        expected = expected.compose(Delay(50), [0])

        expected = expected.compose(Delay(20), [1])
        expected = expected.compose(XGate(), [1])
        expected = expected.compose(Delay(20), [1])
        expected = expected.compose(YGate(), [1])
        expected = expected.compose(Delay(20), [1])
        expected = expected.compose(XGate(), [1])
        expected = expected.compose(Delay(20), [1])
        expected = expected.compose(YGate(), [1])
        expected = expected.compose(Delay(20), [1])

        self.assertEqual(ghz4_dd, expected)
Esempio n. 17
0
    def test_circuit_using_clbit(self):
        """Test a circuit with instructions using a common clbit.

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

        (aligned)
                    ┌───┐       ┌────────────────┐┌─┐┌────────────────┐
        q_0: ───────┤ X ├───────┤ Delay(112[dt]) ├┤M├┤ Delay(160[dt]) ├───
             ┌──────┴───┴──────┐└────────────────┘└╥┘└─────┬───┬──────┘
        q_1: ┤ Delay(1872[dt]) ├───────────────────╫───────┤ X ├──────────
             └┬────────────────┤                   ║       └─╥─┘       ┌─┐
        q_2: ─┤ Delay(432[dt]) ├───────────────────╫─────────╫─────────┤M├
              └────────────────┘                   ║    ┌────╨────┐    └╥┘
        c: 1/══════════════════════════════════════╩════╡ c_0 = T ╞═════╩═
                                                   0    └─────────┘     0

        Looking at the q_0, the total schedule length T becomes
        160 (x) + 112 (aligned delay) + 1600 (measure) + 160 (delay) = 2032.
        The last delay comes from ALAP scheduling called before the AlignMeasure pass,
        which aligns stop times as late as possible, so the start time of x(1).c_if(0)
        and the stop time of measure(0, 0) become T - 160.
        """
        circuit = QuantumCircuit(3, 1)
        circuit.x(0)
        circuit.delay(100, 0, unit="dt")
        circuit.measure(0, 0)
        circuit.x(1).c_if(0, 1)
        circuit.measure(2, 0)

        pm = PassManager([
            # reproduce old behavior of 0.20.0 before #7655
            # currently default write latency is 0
            SetIOLatency(clbit_write_latency=1600, conditional_latency=0),
            ALAPScheduleAnalysis(durations=self.instruction_durations),
            ConstrainedReschedule(acquire_alignment=16),
            PadDelay(fill_very_end=False),
        ])

        aligned_circuit = pm.run(circuit)

        self.assertEqual(aligned_circuit.duration, 2032)

        ref_circuit = QuantumCircuit(3, 1)
        ref_circuit.x(0)
        ref_circuit.delay(112, 0, unit="dt")
        ref_circuit.delay(1872, 1, unit="dt")  # 2032 - 160
        ref_circuit.delay(432, 2, unit="dt")  # 2032 - 1600
        ref_circuit.measure(0, 0)
        ref_circuit.x(1).c_if(0, 1)
        ref_circuit.measure(2, 0)

        self.assertEqual(aligned_circuit, ref_circuit)
    def test_insert_ghz_uhrig(self):
        """Test custom spacing (following Uhrig DD [1]).

        [1] Uhrig, G. "Keeping a quantum bit alive by optimized π-pulse sequences."
        Physical Review Letters 98.10 (2007): 100504.

                   ┌───┐            ┌──────────────┐      ┌───┐       ┌──────────────┐┌───┐»
        q_0: ──────┤ H ├─────────■──┤ Delay(3[dt]) ├──────┤ X ├───────┤ Delay(8[dt]) ├┤ X ├»
             ┌─────┴───┴─────┐ ┌─┴─┐└──────────────┘┌─────┴───┴──────┐└──────────────┘└───┘»
        q_1: ┤ Delay(50[dt]) ├─┤ X ├───────■────────┤ Delay(300[dt]) ├─────────────────────»
             ├───────────────┴┐└───┘     ┌─┴─┐      └────────────────┘                     »
        q_2: ┤ Delay(750[dt]) ├──────────┤ X ├──────────────■──────────────────────────────»
             ├────────────────┤          └───┘            ┌─┴─┐                            »
        q_3: ┤ Delay(950[dt]) ├───────────────────────────┤ X ├────────────────────────────»
             └────────────────┘                           └───┘                            »
        «     ┌───────────────┐┌───┐┌───────────────┐┌───┐┌───────────────┐┌───┐┌───────────────┐»
        «q_0: ┤ Delay(13[dt]) ├┤ X ├┤ Delay(16[dt]) ├┤ X ├┤ Delay(20[dt]) ├┤ X ├┤ Delay(16[dt]) ├»
        «     └───────────────┘└───┘└───────────────┘└───┘└───────────────┘└───┘└───────────────┘»
        «q_1: ───────────────────────────────────────────────────────────────────────────────────»
        «                                                                                        »
        «q_2: ───────────────────────────────────────────────────────────────────────────────────»
        «                                                                                        »
        «q_3: ───────────────────────────────────────────────────────────────────────────────────»
        «                                                                                        »
        «     ┌───┐┌───────────────┐┌───┐┌──────────────┐┌───┐┌──────────────┐
        «q_0: ┤ X ├┤ Delay(13[dt]) ├┤ X ├┤ Delay(8[dt]) ├┤ X ├┤ Delay(3[dt]) ├
        «     └───┘└───────────────┘└───┘└──────────────┘└───┘└──────────────┘
        «q_1: ────────────────────────────────────────────────────────────────
        «
        «q_2: ────────────────────────────────────────────────────────────────
        «
        «q_3: ────────────────────────────────────────────────────────────────
        «
        """
        n = 8
        dd_sequence = [XGate()] * n

        # uhrig specifies the location of the k'th pulse
        def uhrig(k):
            return np.sin(np.pi * (k + 1) / (2 * n + 2))**2

        # convert that to spacing between pulses (whatever finite duration pulses have)
        spacing = []
        for k in range(n):
            spacing.append(uhrig(k) - sum(spacing))
        spacing.append(1 - sum(spacing))

        pm = PassManager([
            ALAPScheduleAnalysis(self.durations),
            PadDynamicalDecoupling(self.durations,
                                   dd_sequence,
                                   qubits=[0],
                                   spacing=spacing),
        ])

        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(3), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(8), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(13), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(16), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(20), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(16), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(13), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(8), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(3), [0])

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

        self.assertEqual(ghz4_dd, expected)
    def test_insert_dd_ghz_xy4(self):
        """Test XY4 sequence of DD gates.

                   ┌───┐            ┌───────────────┐      ┌───┐      ┌───────────────┐»
        q_0: ──────┤ H ├─────────■──┤ Delay(37[dt]) ├──────┤ X ├──────┤ Delay(75[dt]) ├»
             ┌─────┴───┴─────┐ ┌─┴─┐└───────────────┘┌─────┴───┴─────┐└─────┬───┬─────┘»
        q_1: ┤ Delay(50[dt]) ├─┤ X ├────────■────────┤ Delay(12[dt]) ├──────┤ X ├──────»
             ├───────────────┴┐└───┘      ┌─┴─┐      └───────────────┘      └───┘      »
        q_2: ┤ Delay(750[dt]) ├───────────┤ X ├──────────────■─────────────────────────»
             ├────────────────┤           └───┘            ┌─┴─┐                       »
        q_3: ┤ Delay(950[dt]) ├────────────────────────────┤ X ├───────────────────────»
             └────────────────┘                            └───┘                       »
        «           ┌───┐      ┌───────────────┐      ┌───┐      ┌───────────────┐»
        «q_0: ──────┤ Y ├──────┤ Delay(76[dt]) ├──────┤ X ├──────┤ Delay(75[dt]) ├»
        «     ┌─────┴───┴─────┐└─────┬───┬─────┘┌─────┴───┴─────┐└─────┬───┬─────┘»
        «q_1: ┤ Delay(25[dt]) ├──────┤ Y ├──────┤ Delay(26[dt]) ├──────┤ X ├──────»
        «     └───────────────┘      └───┘      └───────────────┘      └───┘      »
        «q_2: ────────────────────────────────────────────────────────────────────»
        «                                                                         »
        «q_3: ────────────────────────────────────────────────────────────────────»
        «                                                                         »
        «           ┌───┐      ┌───────────────┐
        «q_0: ──────┤ Y ├──────┤ Delay(37[dt]) ├─────────────────
        «     ┌─────┴───┴─────┐└─────┬───┬─────┘┌───────────────┐
        «q_1: ┤ Delay(25[dt]) ├──────┤ Y ├──────┤ Delay(12[dt]) ├
        «     └───────────────┘      └───┘      └───────────────┘
        «q_2: ───────────────────────────────────────────────────
        «
        «q_3: ───────────────────────────────────────────────────
        """
        dd_sequence = [XGate(), YGate(), XGate(), YGate()]
        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(37), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(75), [0])
        expected = expected.compose(YGate(), [0])
        expected = expected.compose(Delay(76), [0])
        expected = expected.compose(XGate(), [0])
        expected = expected.compose(Delay(75), [0])
        expected = expected.compose(YGate(), [0])
        expected = expected.compose(Delay(37), [0])

        expected = expected.compose(Delay(12), [1])
        expected = expected.compose(XGate(), [1])
        expected = expected.compose(Delay(25), [1])
        expected = expected.compose(YGate(), [1])
        expected = expected.compose(Delay(26), [1])
        expected = expected.compose(XGate(), [1])
        expected = expected.compose(Delay(25), [1])
        expected = expected.compose(YGate(), [1])
        expected = expected.compose(Delay(12), [1])

        self.assertEqual(ghz4_dd, expected)
Esempio n. 20
0
    def test_mid_circuit_multiq_gates(self):
        """Test circuit with mid circuit measurement and multi qubit gates.

        (input)

             ┌───┐┌────────────────┐┌─┐             ┌─┐
        q_0: ┤ X ├┤ Delay(100[dt]) ├┤M├──■───────■──┤M├
             └───┘└────────────────┘└╥┘┌─┴─┐┌─┐┌─┴─┐└╥┘
        q_1: ────────────────────────╫─┤ X ├┤M├┤ X ├─╫─
                                     ║ └───┘└╥┘└───┘ ║
        c: 2/════════════════════════╩═══════╩═══════╩═
                                     0       1       0

        (output)

                    ┌───┐       ┌────────────────┐┌─┐     ┌─────────────────┐     ┌─┐»
        q_0: ───────┤ X ├───────┤ Delay(112[dt]) ├┤M├──■──┤ Delay(1600[dt]) ├──■──┤M├»
             ┌──────┴───┴──────┐└────────────────┘└╥┘┌─┴─┐└───────┬─┬───────┘┌─┴─┐└╥┘»
        q_1: ┤ Delay(1872[dt]) ├───────────────────╫─┤ X ├────────┤M├────────┤ X ├─╫─»
             └─────────────────┘                   ║ └───┘        └╥┘        └───┘ ║ »
        c: 2/══════════════════════════════════════╩═══════════════╩═══════════════╩═»
                                                   0               1               0 »
        «
        «q_0: ───────────────────
        «     ┌─────────────────┐
        «q_1: ┤ Delay(1600[dt]) ├
        «     └─────────────────┘
        «c: 2/═══════════════════
        «

        Delay for the other channel paired by multi-qubit instruction is also scheduled.
        Delay (1872dt) = X (160dt) + Delay (100dt + extra 12dt) + Measure (1600dt).
        """
        circuit = QuantumCircuit(2, 2)
        circuit.x(0)
        circuit.delay(100, 0, unit="dt")
        circuit.measure(0, 0)
        circuit.cx(0, 1)
        circuit.measure(1, 1)
        circuit.cx(0, 1)
        circuit.measure(0, 0)

        pm = PassManager([
            # reproduce old behavior of 0.20.0 before #7655
            # currently default write latency is 0
            SetIOLatency(clbit_write_latency=1600, conditional_latency=0),
            ALAPScheduleAnalysis(durations=self.instruction_durations),
            ConstrainedReschedule(acquire_alignment=16),
            PadDelay(),
        ])

        aligned_circuit = pm.run(circuit)

        ref_circuit = QuantumCircuit(2, 2)
        ref_circuit.x(0)
        ref_circuit.delay(112, 0, unit="dt")
        ref_circuit.measure(0, 0)
        ref_circuit.delay(160 + 112 + 1600, 1, unit="dt")
        ref_circuit.cx(0, 1)
        ref_circuit.delay(1600, 0, unit="dt")
        ref_circuit.measure(1, 1)
        ref_circuit.cx(0, 1)
        ref_circuit.delay(1600, 1, unit="dt")
        ref_circuit.measure(0, 0)

        self.assertEqual(aligned_circuit, ref_circuit)
Esempio n. 21
0
    def test_random_complicated_circuit(self):
        """Test scheduling complicated circuit with control flow.

        (input)
             ┌────────────────┐   ┌───┐    ░                  ┌───┐   »
        q_0: ┤ Delay(100[dt]) ├───┤ X ├────░──────────────────┤ X ├───»
             └────────────────┘   └─╥─┘    ░       ┌───┐      └─╥─┘   »
        q_1: ───────────────────────╫──────░───────┤ X ├────────╫─────»
                                    ║      ░ ┌─┐   └─╥─┘        ║     »
        q_2: ───────────────────────╫──────░─┤M├─────╫──────────╫─────»
                               ┌────╨────┐ ░ └╥┘┌────╨────┐┌────╨────┐»
        c: 1/══════════════════╡ c_0=0x1 ╞════╩═╡ c_0=0x0 ╞╡ c_0=0x0 ╞»
                               └─────────┘    0 └─────────┘└─────────┘»
        «     ┌────────────────┐┌───┐
        «q_0: ┤ Delay(300[dt]) ├┤ X ├─────■─────
        «     └────────────────┘└───┘   ┌─┴─┐
        «q_1: ────────■─────────────────┤ X ├───
        «           ┌─┴─┐        ┌─┐    └─╥─┘
        «q_2: ──────┤ X ├────────┤M├──────╫─────
        «           └───┘        └╥┘ ┌────╨────┐
        «c: 1/════════════════════╩══╡ c_0=0x0 ╞
        «                         0  └─────────┘

        (ASAP scheduled) duration = 2800 dt
             ┌────────────────┐   ┌───┐    ░ ┌─────────────────┐           »
        q_0: ┤ Delay(200[dt]) ├───┤ X ├────░─┤ Delay(1400[dt]) ├───────────»
             ├────────────────┤   └─╥─┘    ░ ├─────────────────┤   ┌───┐   »
        q_1: ┤ Delay(300[dt]) ├─────╫──────░─┤ Delay(1200[dt]) ├───┤ X ├───»
             ├────────────────┤     ║      ░ └───────┬─┬───────┘   └─╥─┘   »
        q_2: ┤ Delay(300[dt]) ├─────╫──────░─────────┤M├─────────────╫─────»
             └────────────────┘┌────╨────┐ ░         └╥┘        ┌────╨────┐»
        c: 1/══════════════════╡ c_0=0x1 ╞════════════╩═════════╡ c_0=0x0 ╞»
                               └─────────┘            0         └─────────┘»
        «                          ┌───┐   ┌────────────────┐      ┌───┐       »
        «q_0: ─────────────────────┤ X ├───┤ Delay(300[dt]) ├──────┤ X ├───────»
        «                          └─╥─┘   └────────────────┘┌─────┴───┴──────┐»
        «q_1: ───────────────────────╫─────────────■─────────┤ Delay(400[dt]) ├»
        «     ┌────────────────┐     ║           ┌─┴─┐       ├────────────────┤»
        «q_2: ┤ Delay(300[dt]) ├─────╫───────────┤ X ├───────┤ Delay(300[dt]) ├»
        «     └────────────────┘┌────╨────┐      └───┘       └────────────────┘»
        «c: 1/══════════════════╡ c_0=0x0 ╞════════════════════════════════════»
        «                       └─────────┘                                    »
        «                ┌────────────────┐
        «q_0: ─────■─────┤ Delay(700[dt]) ├
        «        ┌─┴─┐   ├────────────────┤
        «q_1: ───┤ X ├───┤ Delay(700[dt]) ├
        «        └─╥─┘   └──────┬─┬───────┘
        «q_2: ─────╫────────────┤M├────────
        «     ┌────╨────┐       └╥┘
        «c: 1/╡ c_0=0x0 ╞════════╩═════════
        «     └─────────┘        0

        (ALAP scheduled) duration = 3100
             ┌────────────────┐   ┌───┐    ░ ┌─────────────────┐           »
        q_0: ┤ Delay(200[dt]) ├───┤ X ├────░─┤ Delay(1400[dt]) ├───────────»
             ├────────────────┤   └─╥─┘    ░ ├─────────────────┤   ┌───┐   »
        q_1: ┤ Delay(300[dt]) ├─────╫──────░─┤ Delay(1200[dt]) ├───┤ X ├───»
             ├────────────────┤     ║      ░ └───────┬─┬───────┘   └─╥─┘   »
        q_2: ┤ Delay(300[dt]) ├─────╫──────░─────────┤M├─────────────╫─────»
             └────────────────┘┌────╨────┐ ░         └╥┘        ┌────╨────┐»
        c: 1/══════════════════╡ c_0=0x1 ╞════════════╩═════════╡ c_0=0x0 ╞»
                               └─────────┘            0         └─────────┘»
        «                          ┌───┐   ┌────────────────┐      ┌───┐       »
        «q_0: ─────────────────────┤ X ├───┤ Delay(300[dt]) ├──────┤ X ├───────»
        «     ┌────────────────┐   └─╥─┘   └────────────────┘┌─────┴───┴──────┐»
        «q_1: ┤ Delay(300[dt]) ├─────╫─────────────■─────────┤ Delay(100[dt]) ├»
        «     ├────────────────┤     ║           ┌─┴─┐       └──────┬─┬───────┘»
        «q_2: ┤ Delay(600[dt]) ├─────╫───────────┤ X ├──────────────┤M├────────»
        «     └────────────────┘┌────╨────┐      └───┘              └╥┘        »
        «c: 1/══════════════════╡ c_0=0x0 ╞══════════════════════════╩═════════»
        «                       └─────────┘                          0         »
        «                ┌────────────────┐
        «q_0: ─────■─────┤ Delay(700[dt]) ├
        «        ┌─┴─┐   ├────────────────┤
        «q_1: ───┤ X ├───┤ Delay(700[dt]) ├
        «        └─╥─┘   └────────────────┘
        «q_2: ─────╫───────────────────────
        «     ┌────╨────┐
        «c: 1/╡ c_0=0x0 ╞══════════════════
        «     └─────────┘

        """
        qc = QuantumCircuit(3, 1)
        qc.delay(100, 0)
        qc.x(0).c_if(0, 1)
        qc.barrier()
        qc.measure(2, 0)
        qc.x(1).c_if(0, 0)
        qc.x(0).c_if(0, 0)
        qc.delay(300, 0)
        qc.cx(1, 2)
        qc.x(0)
        qc.cx(0, 1).c_if(0, 0)
        qc.measure(2, 0)

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

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

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

        expected_asap = QuantumCircuit(3, 1)
        expected_asap.delay(200, 0)  # due to conditional latency of 200dt
        expected_asap.delay(300, 1)
        expected_asap.delay(300, 2)
        expected_asap.x(0).c_if(0, 1)
        expected_asap.barrier()
        expected_asap.delay(1400, 0)
        expected_asap.delay(1200, 1)
        expected_asap.measure(2, 0)
        expected_asap.x(1).c_if(0, 0)
        expected_asap.x(0).c_if(0, 0)
        expected_asap.delay(300, 0)
        expected_asap.x(0)
        expected_asap.delay(300, 2)
        expected_asap.cx(1, 2)
        expected_asap.delay(400, 1)
        expected_asap.cx(0, 1).c_if(0, 0)
        expected_asap.delay(700,
                            0)  # creg is released at t0 of cx(0,1).c_if(0,0)
        expected_asap.delay(
            700, 1
        )  # no creg write until 100dt. thus measure can move left by 300dt.
        expected_asap.delay(300, 2)
        expected_asap.measure(2, 0)
        self.assertEqual(expected_asap, actual_asap)
        self.assertEqual(actual_asap.duration, 3100)

        expected_alap = QuantumCircuit(3, 1)
        expected_alap.delay(200, 0)  # due to conditional latency of 200dt
        expected_alap.delay(300, 1)
        expected_alap.delay(300, 2)
        expected_alap.x(0).c_if(0, 1)
        expected_alap.barrier()
        expected_alap.delay(1400, 0)
        expected_alap.delay(1200, 1)
        expected_alap.measure(2, 0)
        expected_alap.x(1).c_if(0, 0)
        expected_alap.x(0).c_if(0, 0)
        expected_alap.delay(300, 0)
        expected_alap.x(0)
        expected_alap.delay(300, 1)
        expected_alap.delay(600, 2)
        expected_alap.cx(1, 2)
        expected_alap.delay(100, 1)
        expected_alap.cx(0, 1).c_if(0, 0)
        expected_alap.measure(2, 0)
        expected_alap.delay(700, 0)
        expected_alap.delay(700, 1)
        self.assertEqual(expected_alap, actual_alap)
        self.assertEqual(actual_alap.duration, 3100)
Esempio n. 22
0
    def test_parallel_gate_different_length_with_barrier(self):
        """Test circuit having two parallel instruction with different length with barrier.

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

        (expected, ALAP)
             ┌────────────────┐┌───┐ ░ ┌─┐
        q_0: ┤ Delay(200[dt]) ├┤ X ├─░─┤M├───
             └─────┬───┬──────┘└───┘ ░ └╥┘┌─┐
        q_1: ──────┤ X ├─────────────░──╫─┤M├
                   └───┘             ░  ║ └╥┘
        c: 2/═══════════════════════════╩══╩═
                                        0  1

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

        durations = InstructionDurations([("x", [0], 200), ("x", [1], 400),
                                          ("measure", None, 1000)])
        pm = PassManager([ALAPScheduleAnalysis(durations), PadDelay()])
        qc_alap = pm.run(qc)

        alap_expected = QuantumCircuit(2, 2)
        alap_expected.delay(200, 0)
        alap_expected.x(0)
        alap_expected.x(1)
        alap_expected.barrier()
        alap_expected.measure(0, 0)
        alap_expected.measure(1, 1)

        self.assertEqual(qc_alap, alap_expected)

        pm = PassManager([ASAPScheduleAnalysis(durations), PadDelay()])
        qc_asap = pm.run(qc)

        asap_expected = QuantumCircuit(2, 2)
        asap_expected.x(0)
        asap_expected.delay(200, 0)
        asap_expected.x(1)
        asap_expected.barrier()
        asap_expected.measure(0, 0)
        asap_expected.measure(1, 1)

        self.assertEqual(qc_asap, asap_expected)
Esempio n. 23
0
    def test_measure_after_c_if_on_edge_locking(self):
        """Test if ALAP/ASAP schedules circuits with c_if after measure with a common clbit.

        The scheduler is configured to reproduce behavior of the 0.20.0,
        in which clbit lock is applied to the end-edge of measure instruction.
        See https://github.com/Qiskit/qiskit-terra/pull/7655

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

        (ASAP scheduled)
                                ┌─┐┌────────────────┐
        q_0: ───────────────────┤M├┤ Delay(200[dt]) ├─────────────────────
             ┌─────────────────┐└╥┘└─────┬───┬──────┘
        q_1: ┤ Delay(1000[dt]) ├─╫───────┤ X ├────────────────────────────
             └─────────────────┘ ║       └─╥─┘       ┌─┐┌────────────────┐
        q_2: ────────────────────╫─────────╫─────────┤M├┤ Delay(200[dt]) ├
                                 ║    ┌────╨────┐    └╥┘└────────────────┘
        c: 1/════════════════════╩════╡ c_0=0x1 ╞═════╩═══════════════════
                                 0    └─────────┘     0

        (ALAP scheduled)
                                ┌─┐┌────────────────┐
        q_0: ───────────────────┤M├┤ Delay(200[dt]) ├───
             ┌─────────────────┐└╥┘└─────┬───┬──────┘
        q_1: ┤ Delay(1000[dt]) ├─╫───────┤ X ├──────────
             └┬────────────────┤ ║       └─╥─┘       ┌─┐
        q_2: ─┤ Delay(200[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)])

        # lock at the end edge
        actual_asap = PassManager([
            SetIOLatency(clbit_write_latency=1000),
            ASAPScheduleAnalysis(durations),
            PadDelay(),
        ]).run(qc)
        actual_alap = PassManager([
            SetIOLatency(clbit_write_latency=1000),
            ALAPScheduleAnalysis(durations),
            PadDelay(),
        ]).run(qc)

        # start times of 2nd measure depends on ASAP/ALAP
        expected_asap = QuantumCircuit(3, 1)
        expected_asap.measure(0, 0)
        expected_asap.delay(1000, 1)
        expected_asap.x(1).c_if(0, 1)
        expected_asap.measure(2, 0)
        expected_asap.delay(200, 0)
        expected_asap.delay(200, 2)
        self.assertEqual(expected_asap, actual_asap)

        expected_alap = QuantumCircuit(3, 1)
        expected_alap.measure(0, 0)
        expected_alap.delay(1000, 1)
        expected_alap.x(1).c_if(0, 1)
        expected_alap.delay(200, 2)
        expected_alap.measure(2, 0)
        expected_alap.delay(200, 0)
        self.assertEqual(expected_alap, actual_alap)