Beispiel #1
0
    def test_call_gate_and_circuit(self):
        """Test calling circuit with gates."""
        h_control = circuit.QuantumCircuit(2)
        h_control.h(0)

        with pulse.build(self.backend) as schedule:
            with pulse.align_sequential():
                # this is circuit, a subroutine stored as Call instruction
                pulse.call(h_control)
                # this is instruction, not subroutine
                pulse.cx(0, 1)
                # this is macro, not subroutine
                pulse.measure([0, 1])

        # subroutine
        h_reference = compiler.schedule(compiler.transpile(h_control, self.backend), self.backend)

        # gate
        cx_circ = circuit.QuantumCircuit(2)
        cx_circ.cx(0, 1)
        cx_reference = compiler.schedule(compiler.transpile(cx_circ, self.backend), self.backend)

        # measurement
        measure_reference = macros.measure(
            qubits=[0, 1], inst_map=self.inst_map, meas_map=self.configuration.meas_map
        )

        reference = pulse.Schedule()
        reference += pulse.instructions.Call(h_reference)
        reference += cx_reference
        reference += measure_reference << reference.duration

        self.assertScheduleEqual(schedule, reference)
Beispiel #2
0
    def test_transpile_with_instmap(self):
        """Test providing instruction schedule map."""
        instmap = FakeAthens().defaults().instruction_schedule_map
        instmap.add("sx", (0, ), self.custom_sx_q0)
        instmap.add("sx", (1, ), self.custom_sx_q1)

        # Inst map is renewed
        backend = FakeAthens()

        qc = circuit.QuantumCircuit(2)
        qc.sx(0)
        qc.x(0)
        qc.rz(0, 0)
        qc.sx(1)
        qc.measure_all()

        transpiled_qc = transpile(qc,
                                  backend,
                                  inst_map=instmap,
                                  initial_layout=[0, 1])

        ref_calibration = {
            "sx": {
                ((0, ), ()): self.custom_sx_q0,
                ((1, ), ()): self.custom_sx_q1,
            }
        }
        self.assertDictEqual(transpiled_qc.calibrations, ref_calibration)
Beispiel #3
0
    def test_transpile_with_custom_gate(self):
        """Test providing non-basis gate."""
        backend = FakeAthens()
        backend.defaults().instruction_schedule_map.add("my_gate", (0, ),
                                                        self.my_gate_q0,
                                                        arguments=["P0"])
        backend.defaults().instruction_schedule_map.add("my_gate", (1, ),
                                                        self.my_gate_q1,
                                                        arguments=["P0"])

        qc = circuit.QuantumCircuit(2)
        qc.append(circuit.Gate("my_gate", 1, [1.0]), [0])
        qc.append(circuit.Gate("my_gate", 1, [2.0]), [1])

        transpiled_qc = transpile(qc,
                                  backend,
                                  basis_gates=["my_gate"],
                                  initial_layout=[0, 1])

        my_gate_q0_1_0 = self.my_gate_q0.assign_parameters(
            {self.sched_param: 1.0}, inplace=False)
        my_gate_q1_2_0 = self.my_gate_q1.assign_parameters(
            {self.sched_param: 2.0}, inplace=False)

        ref_calibration = {
            "my_gate": {
                ((0, ), (1.0, )): my_gate_q0_1_0,
                ((1, ), (2.0, )): my_gate_q1_2_0,
            }
        }
        self.assertDictEqual(transpiled_qc.calibrations, ref_calibration)
Beispiel #4
0
    def test_rzx_calibration_builder(self):
        """Test whether RZXCalibrationBuilderNoEcho scales pulses correctly."""

        # Define a circuit with one RZX gate and an angle theta.
        theta = pi / 3
        rzx_qc = circuit.QuantumCircuit(2)
        rzx_qc.rzx(theta / 2, 1, 0)

        # Verify that there are no calibrations for this circuit yet.
        self.assertEqual(rzx_qc.calibrations, {})

        # apply the RZXCalibrationBuilderNoEcho.
        pass_ = RZXCalibrationBuilderNoEcho(self.backend)
        cal_qc = PassManager(pass_).run(rzx_qc)
        rzx_qc_duration = schedule(cal_qc, self.backend).duration

        # Check that the calibrations contain the correct instructions
        # and pulses on the correct channels.
        # pylint: disable=no-member
        rzx_qc_instructions = cal_qc.calibrations["rzx"][((1, 0),
                                                          (theta /
                                                           2, ))].instructions
        self.assertEqual(rzx_qc_instructions[0][1].channel, DriveChannel(0))
        self.assertTrue(isinstance(rzx_qc_instructions[0][1], Play))
        self.assertTrue(
            isinstance(rzx_qc_instructions[0][1].pulse, GaussianSquare))
        self.assertEqual(rzx_qc_instructions[1][1].channel, DriveChannel(1))
        self.assertTrue(isinstance(rzx_qc_instructions[1][1], Delay))
        self.assertEqual(rzx_qc_instructions[2][1].channel, ControlChannel(1))
        self.assertTrue(isinstance(rzx_qc_instructions[2][1], Play))
        self.assertTrue(
            isinstance(rzx_qc_instructions[2][1].pulse, GaussianSquare))

        # Calculate the duration of one scaled Gaussian square pulse from the CX gate.
        cx_sched = self.inst_map.get("cx", qubits=(1, 0))

        crs = []
        for time, inst in cx_sched.instructions:

            # Identify the CR pulses.
            if isinstance(inst, Play) and not isinstance(inst, ShiftPhase):
                if isinstance(inst.channel, ControlChannel):
                    crs.append((time, inst))

        pulse_ = crs[0][1].pulse
        amp = pulse_.amp
        width = pulse_.width
        sigma = pulse_.sigma
        n_sigmas = (pulse_.duration - width) / sigma
        sample_mult = 16

        gaussian_area = abs(amp) * sigma * np.sqrt(2 * np.pi) * erf(n_sigmas)
        area = gaussian_area + abs(amp) * width
        target_area = abs(theta) / (np.pi / 2.0) * area
        width = (target_area - gaussian_area) / abs(amp)
        duration = ceil((width + n_sigmas * sigma) / sample_mult) * sample_mult

        # Check whether the durations of the RZX pulse and
        # the scaled CR pulse from the CX gate match.
        self.assertEqual(rzx_qc_duration, duration)
Beispiel #5
0
    def test_pass_alive_with_dcx_ish(self):
        """Test if the pass is not terminated by error with direct CX input."""
        cx_sched = Schedule()
        # Fake direct cr
        cx_sched.insert(0,
                        Play(GaussianSquare(800, 0.2, 64, 544),
                             ControlChannel(1)),
                        inplace=True)
        # Fake direct compensation tone
        # Compensation tone doesn't have dedicated pulse class.
        # So it's reported as a waveform now.
        compensation_tone = Waveform(0.1 * np.ones(800, dtype=complex))
        cx_sched.insert(0,
                        Play(compensation_tone, DriveChannel(0)),
                        inplace=True)

        inst_map = InstructionScheduleMap()
        inst_map.add("cx", (1, 0), schedule=cx_sched)

        theta = pi / 3
        rzx_qc = circuit.QuantumCircuit(2)
        rzx_qc.rzx(theta, 1, 0)

        pass_ = RZXCalibrationBuilder(instruction_schedule_map=inst_map)
        with self.assertWarns(UserWarning):
            # User warning that says q0 q1 is invalid
            cal_qc = PassManager(pass_).run(rzx_qc)
        self.assertEqual(cal_qc, rzx_qc)
Beispiel #6
0
    def test_multiple_instructions_with_different_parameters(self):
        """Test adding many instruction with different parameter binding."""
        backend = FakeAthens()
        backend.defaults().instruction_schedule_map.add("my_gate", (0, ),
                                                        self.my_gate_q0,
                                                        arguments=["P0"])

        qc = circuit.QuantumCircuit(1)
        qc.append(circuit.Gate("my_gate", 1, [1.0]), [0])
        qc.append(circuit.Gate("my_gate", 1, [2.0]), [0])
        qc.append(circuit.Gate("my_gate", 1, [3.0]), [0])

        transpiled_qc = transpile(qc,
                                  backend,
                                  basis_gates=["my_gate"],
                                  initial_layout=[0])

        my_gate_q0_1_0 = self.my_gate_q0.assign_parameters(
            {self.sched_param: 1.0}, inplace=False)
        my_gate_q0_2_0 = self.my_gate_q0.assign_parameters(
            {self.sched_param: 2.0}, inplace=False)
        my_gate_q0_3_0 = self.my_gate_q0.assign_parameters(
            {self.sched_param: 3.0}, inplace=False)

        ref_calibration = {
            "my_gate": {
                ((0, ), (1.0, )): my_gate_q0_1_0,
                ((0, ), (2.0, )): my_gate_q0_2_0,
                ((0, ), (3.0, )): my_gate_q0_3_0,
            }
        }
        self.assertDictEqual(transpiled_qc.calibrations, ref_calibration)
Beispiel #7
0
    def test_u2(self):
        """Test u2 gate."""
        with pulse.build(self.backend) as schedule:
            pulse.u2(np.pi, 0, 0)

        reference_qc = circuit.QuantumCircuit(1)
        reference_qc.append(circuit.library.U2Gate(np.pi, 0), [0])
        reference = compiler.schedule(reference_qc, self.backend)

        self.assertEqual(schedule, reference)
    def test_u3(self):
        """Test u3 gate."""
        with pulse.build(self.backend) as schedule:
            pulse.u3(np.pi, 0, np.pi/2, 0)

        reference_qc = circuit.QuantumCircuit(1)
        reference_qc.u3(np.pi, 0, np.pi/2, 0)
        reference = compiler.schedule(reference_qc, self.backend)

        self.assertEqual(schedule, reference)
Beispiel #9
0
    def test_u3(self):
        """Test u3 gate."""
        with pulse.build(self.backend) as schedule:
            pulse.u3(np.pi / 8, np.pi / 16, np.pi / 4, 0)

        reference_qc = circuit.QuantumCircuit(1)
        reference_qc.append(circuit.library.U3Gate(np.pi / 8, np.pi / 16, np.pi / 4), [0])
        reference = compiler.schedule(reference_qc, self.backend)

        self.assertScheduleEqual(schedule, reference)
    def test_lazy_evaluation_with_transpiler(self):
        """Test that the two cx gates are optimizied away by the transpiler."""
        with pulse.build(self.backend) as schedule:
            pulse.cx(0, 1)
            pulse.cx(0, 1)

        reference_qc = circuit.QuantumCircuit(2)
        reference = compiler.schedule(reference_qc, self.backend)

        self.assertEqual(schedule, reference)
    def test_cx(self):
        """Test cx gate."""
        with pulse.build(self.backend) as schedule:
            pulse.cx(0, 1)

        reference_qc = circuit.QuantumCircuit(2)
        reference_qc.cx(0, 1)
        reference = compiler.schedule(reference_qc, self.backend)

        self.assertEqual(schedule, reference)
    def test_x(self):
        """Test x gate."""
        with pulse.build(self.backend) as schedule:
            pulse.x(0)

        reference_qc = circuit.QuantumCircuit(1)
        reference_qc.x(0)
        reference_qc = compiler.transpile(reference_qc, self.backend)
        reference = compiler.schedule(reference_qc, self.backend)

        self.assertEqual(schedule, reference)
Beispiel #13
0
    def test_u1(self):
        """Test u1 gate."""
        with pulse.build(self.backend) as schedule:
            with pulse.transpiler_settings(layout_method="trivial"):
                pulse.u1(np.pi / 2, 0)

        reference_qc = circuit.QuantumCircuit(1)
        reference_qc.append(circuit.library.U1Gate(np.pi / 2), [0])
        reference = compiler.schedule(reference_qc, self.backend)

        self.assertScheduleEqual(schedule, reference)
Beispiel #14
0
    def test_subroutine_not_transpiled(self):
        """Test called circuit is frozen as a subroutine."""
        subprogram = circuit.QuantumCircuit(1)
        subprogram.x(0)

        transpiler_settings = {"optimization_level": 2}

        with pulse.build(self.backend, default_transpiler_settings=transpiler_settings) as schedule:
            pulse.call(subprogram)
            pulse.call(subprogram)

        self.assertNotEqual(len(target_qobj_transform(schedule).instructions), 0)
    def test_transpile_with_different_qubit(self):
        """Test transpile with qubit without custom gate."""
        backend = FakeAthens()
        backend.defaults().instruction_schedule_map.add("sx", (0,), self.custom_sx_q0)

        qc = circuit.QuantumCircuit(1)
        qc.sx(0)
        qc.measure_all()

        transpiled_qc = transpile(qc, backend, initial_layout=[3])

        self.assertDictEqual(transpiled_qc.calibrations, {})
    def test_call_circuit_with_cregs(self):
        """Test calling of circuit wiht classical registers."""

        qc = circuit.QuantumCircuit(2, 2)
        qc.h(0)
        qc.cx(0, 1)
        qc.measure([0, 1], [0, 1])

        with pulse.build(self.backend) as schedule:
            pulse.call(qc)

        reference_qc = compiler.transpile(qc, self.backend)
        reference = compiler.schedule(reference_qc, self.backend)

        self.assertEqual(schedule, reference)
    def test_measure(self):
        """Test pulse measurement macro against circuit measurement and
        ensure agreement."""
        with pulse.build(self.backend) as schedule:
            with pulse.align_sequential():
                pulse.x(0)
                pulse.measure(0)

        reference_qc = circuit.QuantumCircuit(1, 1)
        reference_qc.x(0)
        reference_qc.measure(0, 0)
        reference_qc = compiler.transpile(reference_qc, self.backend)
        reference = compiler.schedule(reference_qc, self.backend)

        self.assertEqual(schedule, reference)
Beispiel #18
0
    def test_transpile_with_bare_backend(self):
        """Test transpile without custom calibrations."""
        backend = FakeAthens()

        qc = circuit.QuantumCircuit(2)
        qc.sx(0)
        qc.x(0)
        qc.rz(0, 0)
        qc.sx(1)
        qc.measure_all()

        transpiled_qc = transpile(qc, backend, initial_layout=[0, 1])

        ref_calibration = {}
        self.assertDictEqual(transpiled_qc.calibrations, ref_calibration)
    def test_call_circuit(self):
        """Test calling circuit instruction."""
        inst_map = self.inst_map
        reference = inst_map.get('u1', (0,), 0.0)

        u1_qc = circuit.QuantumCircuit(2)
        u1_qc.u1(0.0, 0)

        transpiler_settings = {'optimization_level': 0}

        with pulse.build(self.backend,
                         default_transpiler_settings=transpiler_settings
                         ) as schedule:
            with pulse.align_right():
                builder.call_circuit(u1_qc)

        self.assertEqual(schedule, reference)
    def test_scheduler_settings(self):
        """Test the circuit scheduler settings context."""
        inst_map = pulse.InstructionScheduleMap()
        d0 = pulse.DriveChannel(0)
        test_x_sched = pulse.Schedule()
        test_x_sched += instructions.Delay(10, d0)
        inst_map.add('x', (0,), test_x_sched)

        x_qc = circuit.QuantumCircuit(2)
        x_qc.x(0)

        with pulse.build(backend=self.backend) as schedule:
            with pulse.transpiler_settings(basis_gates=['x']):
                with pulse.circuit_scheduler_settings(inst_map=inst_map):
                    builder.call_circuit(x_qc)

        self.assertEqual(schedule, test_x_sched)
Beispiel #21
0
    def test_call_circuit(self):
        """Test calling circuit instruction."""
        inst_map = self.inst_map
        reference = inst_map.get("u1", (0,), 0.0)

        ref_sched = pulse.Schedule()
        ref_sched += pulse.instructions.Call(reference)

        u1_qc = circuit.QuantumCircuit(2)
        u1_qc.append(circuit.library.U1Gate(0.0), [0])

        transpiler_settings = {"optimization_level": 0}

        with pulse.build(self.backend, default_transpiler_settings=transpiler_settings) as schedule:
            with pulse.align_right():
                builder.call(u1_qc)

        self.assertScheduleEqual(schedule, ref_sched)
    def test_transpiler_settings(self):
        """Test the transpiler settings context.

        Tests that two cx gates are optimized away with higher optimization level.
        """
        twice_cx_qc = circuit.QuantumCircuit(2)
        twice_cx_qc.cx(0, 1)
        twice_cx_qc.cx(0, 1)

        with pulse.build(self.backend) as schedule:
            with pulse.transpiler_settings(optimization_level=0):
                builder.call_circuit(twice_cx_qc)
        self.assertNotEqual(len(schedule.instructions), 0)

        with pulse.build(self.backend) as schedule:
            with pulse.transpiler_settings(optimization_level=3):
                builder.call_circuit(twice_cx_qc)
        self.assertEqual(len(schedule.instructions), 0)
    def test_transpile_with_custom_basis_gate(self):
        """Test transpile with custom calibrations."""
        backend = FakeAthens()
        backend.defaults().instruction_schedule_map.add("sx", (0,), self.custom_sx_q0)
        backend.defaults().instruction_schedule_map.add("sx", (1,), self.custom_sx_q1)

        qc = circuit.QuantumCircuit(2)
        qc.sx(0)
        qc.x(0)
        qc.rz(0, 0)
        qc.sx(1)
        qc.measure_all()

        transpiled_qc = transpile(qc, backend, initial_layout=[0, 1])

        ref_calibration = {
            "sx": {
                ((0,), ()): self.custom_sx_q0,
                ((1,), ()): self.custom_sx_q1,
            }
        }
        self.assertDictEqual(transpiled_qc.calibrations, ref_calibration)
    def test_transpile_with_multiple_circuits(self):
        """Test transpile with multiple circuits with custom gate."""
        backend = FakeAthens()
        backend.defaults().instruction_schedule_map.add(
            "my_gate", (0,), self.my_gate_q0, arguments=["P0"]
        )

        params = [0.0, 1.0, 2.0, 3.0]
        circs = []
        for param in params:
            qc = circuit.QuantumCircuit(1)
            qc.append(circuit.Gate("my_gate", 1, [param]), [0])
            circs.append(qc)

        transpiled_qcs = transpile(circs, backend, basis_gates=["my_gate"], initial_layout=[0])

        for param, transpiled_qc in zip(params, transpiled_qcs):
            my_gate_q0_x = self.my_gate_q0.assign_parameters(
                {self.sched_param: param}, inplace=False
            )
            ref_calibration = {"my_gate": {((0,), (param,)): my_gate_q0_x}}
            self.assertDictEqual(transpiled_qc.calibrations, ref_calibration)
    def test_complex_build(self):
        """Test a general program build with nested contexts,
        circuits and macros."""
        d0 = pulse.DriveChannel(0)
        d1 = pulse.DriveChannel(1)
        d2 = pulse.DriveChannel(2)
        delay_dur = 19
        short_dur = 31
        long_dur = 101

        with pulse.build(self.backend) as schedule:
            with pulse.align_sequential():
                pulse.delay(delay_dur, d0)
                pulse.u2(0, pi/2, 1)
            with pulse.align_right():
                pulse.play(library.Constant(short_dur, 0.1), d1)
                pulse.play(library.Constant(long_dur, 0.1), d2)
                pulse.u2(0, pi/2, 1)
            with pulse.align_left():
                pulse.u2(0, pi/2, 0)
                pulse.u2(0, pi/2, 1)
                pulse.u2(0, pi/2, 0)
            pulse.measure(0)

        # prepare and schedule circuits that will be used.
        single_u2_qc = circuit.QuantumCircuit(2)
        single_u2_qc.u2(0, pi/2, 1)
        single_u2_qc = compiler.transpile(single_u2_qc, self.backend)
        single_u2_sched = compiler.schedule(single_u2_qc, self.backend)

        # sequential context
        sequential_reference = pulse.Schedule()
        sequential_reference += instructions.Delay(delay_dur, d0)
        sequential_reference.insert(delay_dur, single_u2_sched, inplace=True)

        # align right
        align_right_reference = pulse.Schedule()
        align_right_reference += pulse.Play(
            library.Constant(long_dur, 0.1), d2)
        align_right_reference.insert(long_dur-single_u2_sched.duration,
                                     single_u2_sched,
                                     inplace=True)
        align_right_reference.insert(
            long_dur-single_u2_sched.duration-short_dur,
            pulse.Play(library.Constant(short_dur, 0.1), d1),
            inplace=True)

        # align left
        triple_u2_qc = circuit.QuantumCircuit(2)
        triple_u2_qc.u2(0, pi/2, 0)
        triple_u2_qc.u2(0, pi/2, 1)
        triple_u2_qc.u2(0, pi/2, 0)
        triple_u2_qc = compiler.transpile(triple_u2_qc, self.backend)
        align_left_reference = compiler.schedule(
            triple_u2_qc, self.backend, method='alap')

        # measurement
        measure_reference = macros.measure(qubits=[0],
                                           inst_map=self.inst_map,
                                           meas_map=self.configuration.meas_map)
        reference = pulse.Schedule()
        reference += sequential_reference
        # Insert so that the long pulse on d2 occurs as early as possible
        # without an overval on d1.
        insert_time = (reference.ch_stop_time(d1) -
                       align_right_reference.ch_start_time(d1))
        reference.insert(insert_time,
                         align_right_reference,
                         inplace=True)
        reference.insert(reference.ch_stop_time(d0, d1),
                         align_left_reference,
                         inplace=True)
        reference += measure_reference
        self.assertEqual(schedule, reference)
if __name__ == "__main__":
    compilation_text = ""

    I = ls.PauliOperator.I
    X = ls.PauliOperator.X
    Y = ls.PauliOperator.Y
    Z = ls.PauliOperator.Z

    # Construct in parallel a quiskit circuit to print and an equivalent pauli circuit to execute
    # The construtction of the pauli rotation circuit get's kick started with gates from the other circuit,
    # so it is initialized below

    crz = qkcirc.ClassicalRegister(1)
    crx = qkcirc.ClassicalRegister(1)
    qreg = qkcirc.QuantumRegister(3)
    qiskit_circ = qkcirc.QuantumCircuit(qreg, crx, crz)

    # Entangle a Bell pair. 1 is Alice's 2 is Bob's
    qiskit_circ.h(1)
    qiskit_circ.cx(1, 2)
    qiskit_circ.barrier()

    # Create a non trivial state in q0, the one Alice wants to send to Bob.
    qiskit_circ.h(0)
    qiskit_circ.t(0)
    qiskit_circ.h(0)
    qiskit_circ.barrier()

    # Alice's  part of the teleportation
    qiskit_circ.cx(0, 1)
    qiskit_circ.h(0)