Ejemplo n.º 1
0
    def remove_final_measurements(self):
        """Removes final measurement on all qubits if they are present.
        Deletes the ClassicalRegister that was used to store the values from these measurements
        if it is idle.
        """
        # pylint: disable=cyclic-import
        from qiskit.transpiler.passes import RemoveFinalMeasurements
        from qiskit.converters import circuit_to_dag
        dag = circuit_to_dag(self)
        remove_final_meas = RemoveFinalMeasurements()
        new_dag = remove_final_meas.run(dag)

        # Set self's cregs and instructions to match the new DAGCircuit's
        self.data.clear()
        self.cregs = list(new_dag.cregs.values())

        for node in new_dag.topological_op_nodes():
            qubits = []
            for qubit in node.qargs:
                qubits.append(new_dag.qregs[qubit.register.name][qubit.index])

            clbits = []
            for clbit in node.cargs:
                clbits.append(new_dag.cregs[clbit.register.name][clbit.index])

            # Get arguments for classical condition (if any)
            inst = node.op.copy()
            inst.condition = node.condition
            self.append(inst, qubits, clbits)
Ejemplo n.º 2
0
def get_width_of_circuit(circuit):
    """Get number of qubits required by the circuit"""
    remove_final_meas = RemoveFinalMeasurements()
    active_qubits = [
        qubit
        for qubit in circuit.qubits if qubit not in remove_final_meas.run(
            circuit_to_dag(circuit)).idle_wires()
    ]
    return len(active_qubits)
    def test_multi_bit_register_kept_if_not_measured_clbit_busy(self):
        """
        A multi-bit register is kept if it contains a busy bit even if
        the measure destination bit itself is idle.
        """

        def expected_dag():
            q0 = QuantumRegister(1, "q0")
            c0 = ClassicalRegister(2, "c0")
            qc = QuantumCircuit(q0, c0)
            qc.x(q0[0]).c_if(c0[0], 0)
            return circuit_to_dag(qc)

        q0 = QuantumRegister(1, "q0")
        c0 = ClassicalRegister(2, "c0")
        qc = QuantumCircuit(q0, c0)

        # make c0[0] busy
        qc.x(q0[0]).c_if(c0[0], 0)

        # measure into not busy c0[1]
        qc.measure(0, c0[1])

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        # c0 should not be removed because it has busy bit c0[0]
        self.assertListEqual(list(dag.cregs.values()), [c0])

        # note: c0[1] should not be removed even though it is now idle
        # because it is referenced by creg c0.
        self.assertListEqual(dag.clbits, list(c0))
        self.assertEqual(dag, expected_dag())
    def test_final_barriers_and_measures_complex(self):
        """Test complex final barrier and measure removal."""

        def expected_dag():
            q0 = QuantumRegister(5, "q0")
            c1 = ClassicalRegister(1, "c1")
            qc = QuantumCircuit(q0, c1)
            qc.h(q0[0])
            return circuit_to_dag(qc)

        q0 = QuantumRegister(5, "q0")
        c0 = ClassicalRegister(1, "c0")
        c1 = ClassicalRegister(1, "c1")
        qc = QuantumCircuit(q0, c0, c1)

        qc.measure(q0[1], c0)
        qc.h(q0[0])
        qc.measure(q0[0], c0[0])
        qc.barrier()
        qc.barrier(q0[2], q0[3])
        qc.measure_all()
        qc.barrier(q0[4])

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertEqual(dag, expected_dag())
    def test_register_kept_if_measured_clbit_busy(self):
        """
        A register is kept if the measure destination bit is still
        busy after measure removal.
        """

        def expected_dag():
            q0 = QuantumRegister(1, "q0")
            c0 = ClassicalRegister(1, "c0")
            qc = QuantumCircuit(q0, c0)
            qc.x(0).c_if(c0[0], 0)
            return circuit_to_dag(qc)

        q0 = QuantumRegister(1, "q0")
        c0 = ClassicalRegister(1, "c0")
        qc = QuantumCircuit(q0, c0)

        # make c0 busy
        qc.x(0).c_if(c0[0], 0)

        # measure into c0
        qc.measure(0, c0[0])

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertListEqual(list(dag.cregs.values()), [c0])
        self.assertListEqual(dag.clbits, list(c0))
        self.assertEqual(dag, expected_dag())
    def test_remove_chained_final_measurements(self):
        """Remove successive final measurements."""

        def expected_dag():
            q0 = QuantumRegister(1, "q0")
            q1 = QuantumRegister(1, "q1")
            c0 = ClassicalRegister(1, "c0")
            qc = QuantumCircuit(q0, c0, q1)

            qc.measure(q0, c0)
            qc.measure(q0, c0)
            qc.barrier()
            qc.h(q1)

            return circuit_to_dag(qc)

        q0 = QuantumRegister(1, "q0")
        q1 = QuantumRegister(1, "q1")
        c0 = ClassicalRegister(1, "c0")
        c1 = ClassicalRegister(1, "c1")
        qc = QuantumCircuit(q0, c0, q1, c1)

        qc.measure(q0, c0)
        qc.measure(q0, c0)
        qc.barrier()
        qc.h(q1)
        qc.measure(q1, c1)
        qc.measure(q0, c1)

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertEqual(dag, expected_dag())
    def test_remove_clbits_without_register(self):
        """clbits of final measurements not in a register are removed."""

        def expected_dag():
            q0 = QuantumRegister(1, "q0")
            qc = QuantumCircuit(q0)
            return circuit_to_dag(qc)

        q0 = QuantumRegister(1, "q0")
        qc = QuantumCircuit(q0)

        # Add clbit without adding register
        qc.add_bits([Clbit()])

        self.assertFalse(qc.cregs)

        # Measure to regless clbit
        qc.measure(0, 0)

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertFalse(dag.cregs)
        self.assertFalse(dag.clbits)
        self.assertEqual(dag, expected_dag())
    def test_multi_reg_shared_bits_removed(self):
        """All registers sharing removed bits should be removed."""

        def expected_dag():
            q0 = QuantumRegister(2, "q0")
            qc = QuantumCircuit(q0)
            return circuit_to_dag(qc)

        q0 = QuantumRegister(2, "q0")
        c0 = ClassicalRegister(2, "c0")
        qc = QuantumCircuit(q0, c0)

        # Create reg with shared bits (same as c0)
        c1 = ClassicalRegister(name="c1", bits=qc.clbits)
        qc.add_register(c1)

        # measure into all clbits of c0
        qc.measure(0, c0[0])
        qc.measure(1, c0[1])

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertFalse(dag.cregs)
        self.assertFalse(dag.clbits)
        self.assertEqual(dag, expected_dag())
    def test_final_measures_share_dest(self):
        """Multiple final measurements use the same clbit."""
        def expected_dag():
            qc = QuantumCircuit(QuantumRegister(2, "q0"))
            return circuit_to_dag(qc)

        rq = QuantumRegister(2, "q0")
        rc = ClassicalRegister(1, "c0")
        qc = QuantumCircuit(rq, rc)

        qc.measure(0, 0)
        qc.measure(1, 0)

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertEqual(dag, expected_dag())
    def test_final_barriers_and_measures_complex(self):
        """Test complex final barrier and measure removal."""
        def expected_dag():
            q0 = QuantumRegister(5, "q0")
            c1 = ClassicalRegister(1, "c1")
            qc = QuantumCircuit(q0, c1)
            qc.h(q0[0])
            return circuit_to_dag(qc)

        #       ┌───┐┌─┐ ░     ░ ┌─┐
        # q0_0: ┤ H ├┤M├─░─────░─┤M├───────────────
        #       └┬─┬┘└╥┘ ░     ░ └╥┘┌─┐
        # q0_1: ─┤M├──╫──░─────░──╫─┤M├────────────
        #        └╥┘  ║  ░  ░  ░  ║ └╥┘┌─┐
        # q0_2: ──╫───╫──░──░──░──╫──╫─┤M├─────────
        #         ║   ║  ░  ░  ░  ║  ║ └╥┘┌─┐
        # q0_3: ──╫───╫──░──░──░──╫──╫──╫─┤M├──────
        #         ║   ║  ░  ░  ░  ║  ║  ║ └╥┘┌─┐ ░
        # q0_4: ──╫───╫──░─────░──╫──╫──╫──╫─┤M├─░─
        #         ║   ║  ░     ░  ║  ║  ║  ║ └╥┘ ░
        # c0: 1/══╩═══╩═══════════╬══╬══╬══╬══╬════
        #         0   0           ║  ║  ║  ║  ║
        #                         ║  ║  ║  ║  ║
        # c1: 1/══════════════════╬══╬══╬══╬══╬════
        #                         ║  ║  ║  ║  ║
        # meas: 5/════════════════╩══╩══╩══╩══╩════
        #                         0  1  2  3  4
        q0 = QuantumRegister(5, "q0")
        c0 = ClassicalRegister(1, "c0")
        c1 = ClassicalRegister(1, "c1")
        qc = QuantumCircuit(q0, c0, c1)

        qc.measure(q0[1], c0)
        qc.h(q0[0])
        qc.measure(q0[0], c0[0])
        qc.barrier()
        qc.barrier(q0[2], q0[3])
        qc.measure_all()
        qc.barrier(q0[4])

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertEqual(dag, expected_dag())
    def test_overlapping_register_removal(self):
        """Only registers that become idle directly as a result of
        final op removal are removed. In this test, a 5-bit creg
        is implicitly created with its own bits, along with cregs
        ``c0_lower_3`` and ``c0_upper_3`` which reuse those underlying bits.
        ``c0_lower_3`` and ``c0_upper_3`` reference only 1 bit in common.
        A final measure is performed into a bit that exists in ``c0_lower_3``
        but not in ``c0_upper_3``, and subsequently is removed. Consequently,
        both ``c0_lower_3`` and the 5-bit register are removed, because they
        have become unused as a result of the final measure removal.
        ``c0_upper_3`` remains, because it was idle beforehand, not as a
        result of the measure removal, along with all of its bits,
        including the bit shared with ``c0_lower_3``."""

        def expected_dag():
            q0 = QuantumRegister(3, "q0")
            c0 = ClassicalRegister(5, "c0")
            c0_upper_3 = ClassicalRegister(name="c0_upper_3", bits=c0[2:])

            # note c0 is *not* added to circuit!
            qc = QuantumCircuit(q0, c0_upper_3)
            return circuit_to_dag(qc)

        q0 = QuantumRegister(3, "q0")
        c0 = ClassicalRegister(5, "c0")
        qc = QuantumCircuit(q0, c0)

        c0_lower_3 = ClassicalRegister(name="c0_lower_3", bits=c0[:3])
        c0_upper_3 = ClassicalRegister(name="c0_upper_3", bits=c0[2:])
        # Only qc.clbits[2] is shared between the two.

        qc.add_register(c0_lower_3)
        qc.add_register(c0_upper_3)

        qc.measure(0, c0_lower_3[0])

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertListEqual(list(dag.cregs.values()), [c0_upper_3])
        self.assertListEqual(dag.clbits, list(c0_upper_3))
        self.assertEqual(dag, expected_dag())
    def test_multi_bit_register_removed_if_all_bits_idle(self):
        """A multibit register is removed when all bits are idle."""
        def expected_dag():
            q0 = QuantumRegister(1, "q0")
            qc = QuantumCircuit(q0)
            return circuit_to_dag(qc)

        q0 = QuantumRegister(1, "q0")
        c0 = ClassicalRegister(2, "c0")
        qc = QuantumCircuit(q0, c0)

        # measure into single bit c0[0] of c0
        qc.measure(0, 0)

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertFalse(dag.cregs)
        self.assertFalse(dag.clbits)
        self.assertEqual(dag, expected_dag())
    def test_multi_bit_register_removed_with_clbits(self):
        """Remove register when all clbits removed."""
        def expected_dag():
            q0 = QuantumRegister(2, "q0")
            qc = QuantumCircuit(q0)
            return circuit_to_dag(qc)

        q0 = QuantumRegister(2, "q0")
        c0 = ClassicalRegister(2, "c0")
        qc = QuantumCircuit(q0, c0)

        # measure into all clbits of c0
        qc.measure(0, 0)
        qc.measure(1, 1)

        dag = circuit_to_dag(qc)
        dag = RemoveFinalMeasurements().run(dag)

        self.assertFalse(dag.cregs)
        self.assertFalse(dag.clbits)
        self.assertEqual(dag, expected_dag())
Ejemplo n.º 14
0
def randomize(qpu_name, num_of_qubits, shots, min_depth_of_circuit,
              max_depth_of_circuit, num_of_circuits, token):
    """Create randomized circuits with given properties and jobs to run them on IBM backends."""
    sim_name = 'ibmq_qasm_simulator'
    backend_sim = ibmq_handler.get_qpu(token, sim_name)
    backend_real = ibmq_handler.get_qpu(token, qpu_name)
    locations = []

    # create the given number of circuits of given width and depth
    for i in range(min_depth_of_circuit, max_depth_of_circuit + 1):
        for j in range(num_of_circuits):
            rowcount = db.session.query(Benchmark).count()
            benchmark_id = rowcount // 2
            # create randomized circuits and transpile them for both backends
            qx = random_circuit(num_qubits=num_of_qubits,
                                depth=i,
                                measure=True)
            original_number_of_multi_qubit_gates = qx.num_nonlocal_gates()
            qcircuit_sim = transpile(qx,
                                     backend=backend_sim,
                                     optimization_level=3)
            qcircuit_real = transpile(qx,
                                      backend=backend_real,
                                      optimization_level=3)
            # ensure that the width of the circuit is correctly saved in the db
            remove_final_meas = RemoveFinalMeasurements()
            active_qubits_real = [
                qubit for qubit in qcircuit_real.qubits
                if qubit not in remove_final_meas.run(
                    circuit_to_dag(qcircuit_real)).idle_wires()
            ]
            transpiled_depth_sim = qcircuit_sim.depth()
            transpiled_width_sim = qcircuit_sim.num_qubits
            transpiled_number_of_multi_qubit_gates_sim = qcircuit_sim.num_nonlocal_gates(
            )
            transpiled_depth_real = qcircuit_real.depth()
            transpiled_width_real = len(active_qubits_real)
            transpiled_number_of_multi_qubit_gates_real = qcircuit_real.num_nonlocal_gates(
            )

            location_sim = run(circuit=qcircuit_sim,
                               backend=sim_name,
                               token=token,
                               shots=shots,
                               benchmark_id=benchmark_id,
                               original_depth=i,
                               original_width=num_of_qubits,
                               original_number_of_multi_qubit_gates=
                               original_number_of_multi_qubit_gates,
                               transpiled_depth=transpiled_depth_sim,
                               transpiled_width=transpiled_width_sim,
                               transpiled_number_of_multi_qubit_gates=
                               transpiled_number_of_multi_qubit_gates_sim)

            location_real = run(circuit=qcircuit_real,
                                backend=qpu_name,
                                token=token,
                                shots=shots,
                                benchmark_id=benchmark_id,
                                original_depth=i,
                                original_width=num_of_qubits,
                                original_number_of_multi_qubit_gates=
                                original_number_of_multi_qubit_gates,
                                transpiled_depth=transpiled_depth_real,
                                transpiled_width=transpiled_width_real,
                                transpiled_number_of_multi_qubit_gates=
                                transpiled_number_of_multi_qubit_gates_real)
            location_benchmark = '/qiskit-service/api/v1.0/benchmarks/' + str(
                benchmark_id)
            locations.append({
                'result-simulator': str(location_sim),
                'result-real-backend': str(location_real),
                'result-benchmark': str(location_benchmark)
            })

    return locations