def test_append_resolves_numpy_integers(self, index):
     """Test that Numpy's integers can be used to reference qubits and clbits."""
     qubits = [Qubit(), Qubit()]
     clbits = [Clbit(), Clbit()]
     test = QuantumCircuit(qubits, clbits)
     test.append(Measure(), [index], [index])
     expected = QuantumCircuit(qubits, clbits)
     expected.append(Measure(), [qubits[int(index)]], [clbits[int(index)]])
     self.assertEqual(test, expected)
 def test_append_resolves_integers(self, index):
     """Test that integer arguments to append are correctly resolved."""
     # We need to assume that appending ``Bit`` instances will always work, so we have something
     # to test against.
     qubits = [Qubit(), Qubit()]
     clbits = [Clbit(), Clbit()]
     test = QuantumCircuit(qubits, clbits)
     test.append(Measure(), [index], [index])
     expected = QuantumCircuit(qubits, clbits)
     expected.append(Measure(), [qubits[index]], [clbits[index]])
     self.assertEqual(test, expected)
 def test_append_rejects_bits_not_in_circuit(self):
     """Test that append rejects bits that are not in the circuit."""
     test = QuantumCircuit(2, 2)
     with self.subTest("qubit"), self.assertRaisesRegex(CircuitError, "not in the circuit"):
         test.append(Measure(), [Qubit()], [test.clbits[0]])
     with self.subTest("clbit"), self.assertRaisesRegex(CircuitError, "not in the circuit"):
         test.append(Measure(), [test.qubits[0]], [Clbit()])
     with self.subTest("qubit list"), self.assertRaisesRegex(CircuitError, "not in the circuit"):
         test.append(Measure(), [[test.qubits[0], Qubit()]], [test.clbits])
     with self.subTest("clbit list"), self.assertRaisesRegex(CircuitError, "not in the circuit"):
         test.append(Measure(), [test.qubits], [[test.clbits[0], Clbit()]])
 def test_standalone_and_shared_out_of_order(self):
     """Test circuit with register bits inserted out of order."""
     qr_standalone = QuantumRegister(2, "standalone")
     qubits = [Qubit() for _ in range(5)]
     clbits = [Clbit() for _ in range(5)]
     qc = QuantumCircuit()
     qc.add_bits(qubits)
     qc.add_bits(clbits)
     random.shuffle(qubits)
     random.shuffle(clbits)
     qr = QuantumRegister(bits=qubits)
     cr = ClassicalRegister(bits=clbits)
     qc.add_register(qr)
     qc.add_register(cr)
     qr_standalone = QuantumRegister(2, "standalone")
     cr_standalone = ClassicalRegister(2, "classical_standalone")
     qc.add_bits([qr_standalone[1], qr_standalone[0]])
     qc.add_bits([cr_standalone[1], cr_standalone[0]])
     qc.add_register(qr_standalone)
     qc.add_register(cr_standalone)
     qc.unitary(random_unitary(32, seed=42), qr)
     qc.unitary(random_unitary(4, seed=100), qr_standalone)
     qc.measure(qr, cr)
     qc.measure(qr_standalone, cr_standalone)
     qpy_file = io.BytesIO()
     dump(qc, qpy_file)
     qpy_file.seek(0)
     new_circ = load(qpy_file)[0]
     self.assertEqual(qc, new_circ)
    def test_append_rejects_bit_of_wrong_type(self):
        """Test that append rejects bits of the wrong type in an argument list."""
        qubits = [Qubit(), Qubit()]
        clbits = [Clbit(), Clbit()]
        test = QuantumCircuit(qubits, clbits)
        with self.subTest("c to q"), self.assertRaisesRegex(CircuitError, "Incorrect bit type"):
            test.append(Measure(), [clbits[0]], [clbits[1]])
        with self.subTest("q to c"), self.assertRaisesRegex(CircuitError, "Incorrect bit type"):
            test.append(Measure(), [qubits[0]], [qubits[1]])

        with self.subTest("none to q"), self.assertRaisesRegex(CircuitError, "Incorrect bit type"):
            test.append(Measure(), [Bit()], [clbits[0]])
        with self.subTest("none to c"), self.assertRaisesRegex(CircuitError, "Incorrect bit type"):
            test.append(Measure(), [qubits[0]], [Bit()])
        with self.subTest("none list"), self.assertRaisesRegex(CircuitError, "Incorrect bit type"):
            test.append(Measure(), [[qubits[0], Bit()]], [[clbits[0], Bit()]])
    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_hybrid_standalone_register(self):
     """Test qpy serialization with registers that mix bit types"""
     qr = QuantumRegister(5, "foo")
     qr = QuantumRegister(name="bar", bits=qr[:3] + [Qubit(), Qubit()])
     cr = ClassicalRegister(5, "foo")
     cr = ClassicalRegister(name="classical_bar", bits=cr[:3] + [Clbit(), Clbit()])
     qc = QuantumCircuit(qr, cr)
     qc.h(0)
     qc.cx(0, 1)
     qc.cx(0, 2)
     qc.cx(0, 3)
     qc.cx(0, 4)
     qc.measure(qr, cr)
     qpy_file = io.BytesIO()
     dump(qc, qpy_file)
     qpy_file.seek(0)
     new_circ = load(qpy_file)[0]
     self.assertEqual(qc, new_circ)
    def test_reverse_bits_with_registerless_bits(self):
        """Test reversing order of registerless bits."""
        q0 = Qubit()
        q1 = Qubit()
        c0 = Clbit()
        c1 = Clbit()
        qc = QuantumCircuit([q0, q1], [c0, c1])
        qc.h(0)
        qc.cx(0, 1)
        qc.x(0).c_if(1, True)
        qc.measure(0, 0)

        expected = QuantumCircuit([c1, c0], [q1, q0])
        expected.h(1)
        expected.cx(1, 0)
        expected.x(1).c_if(0, True)
        expected.measure(1, 1)

        self.assertEqual(qc.reverse_bits(), expected)
Beispiel #9
0
def _read_circuit(file_obj):
    header, name, metadata = _read_header(file_obj)
    (
        name_size,  # pylint: disable=unused-variable
        global_phase,
        num_qubits,
        num_clbits,
        metadata_size,  # pylint: disable=unused-variable
        num_registers,
        num_instructions,
    ) = header
    registers = {}
    if num_registers > 0:
        circ = QuantumCircuit(name=name,
                              global_phase=global_phase,
                              metadata=metadata)
        # TODO Update to handle registers composed of not continuous bit
        # indices. Right now this only works for standalone registers or
        # registers composed bit indices that are continuous
        registers = _read_registers(file_obj, num_registers)
        for qreg in registers["q"].values():
            min_index = min(qreg["index_map"].keys())
            qubits = [Qubit() for i in range(min_index - len(circ.qubits))]
            if qubits:
                circ.add_bits(qubits)
            circ.add_register(qreg["register"])
        for creg in registers["c"].values():
            min_index = min(creg["index_map"].keys())
            clbits = [Clbit() for i in range(min_index - len(circ.clbits))]
            if clbits:
                circ.add_bits(clbits)
            circ.add_register(creg["register"])
    else:
        circ = QuantumCircuit(
            num_qubits,
            num_clbits,
            name=name,
            global_phase=global_phase,
            metadata=metadata,
        )
    custom_instructions = _read_custom_instructions(file_obj)
    for _instruction in range(num_instructions):
        _read_instruction(file_obj, circ, registers, custom_instructions)

    return circ
    def test_remove_final_measurements_bit_locations(self):
        """Test remove_final_measurements properly recalculates clbit indicies
        and preserves order of remaining cregs and clbits.
        """
        c0 = ClassicalRegister(1)
        c1_0 = Clbit()
        c2 = ClassicalRegister(1)
        c3 = ClassicalRegister(1)

        # add an individual bit that's not in any register of this circuit
        circuit = QuantumCircuit(QuantumRegister(1), c0, [c1_0], c2, c3)

        circuit.measure(0, c1_0)
        circuit.measure(0, c2[0])

        # assert cregs and clbits before measure removal
        self.assertEqual(circuit.cregs, [c0, c2, c3])
        self.assertEqual(circuit.clbits, [c0[0], c1_0, c2[0], c3[0]])

        # assert clbit indices prior to measure removal
        self.assertEqual(circuit.find_bit(c0[0]), BitLocations(0, [(c0, 0)]))
        self.assertEqual(circuit.find_bit(c1_0), BitLocations(1, []))
        self.assertEqual(circuit.find_bit(c2[0]), BitLocations(2, [(c2, 0)]))
        self.assertEqual(circuit.find_bit(c3[0]), BitLocations(3, [(c3, 0)]))

        circuit.remove_final_measurements()

        # after measure removal, creg c2 should be gone, as should lone bit c1_0
        # and c0 should still come before c3
        self.assertEqual(circuit.cregs, [c0, c3])
        self.assertEqual(circuit.clbits, [c0[0], c3[0]])

        # there should be no gaps in clbit indices
        # e.g. c3[0] is now the second clbit
        self.assertEqual(circuit.find_bit(c0[0]), BitLocations(0, [(c0, 0)]))
        self.assertEqual(circuit.find_bit(c3[0]), BitLocations(1, [(c3, 0)]))
 def test_mixed_registers(self):
     """Test circuit with mix of standalone and shared registers."""
     qubits = [Qubit() for _ in range(5)]
     clbits = [Clbit() for _ in range(5)]
     qc = QuantumCircuit()
     qc.add_bits(qubits)
     qc.add_bits(clbits)
     qr = QuantumRegister(bits=qubits)
     cr = ClassicalRegister(bits=clbits)
     qc.add_register(qr)
     qc.add_register(cr)
     qr_standalone = QuantumRegister(2, "standalone")
     qc.add_register(qr_standalone)
     cr_standalone = ClassicalRegister(2, "classical_standalone")
     qc.add_register(cr_standalone)
     qc.unitary(random_unitary(32, seed=42), qr)
     qc.unitary(random_unitary(4, seed=100), qr_standalone)
     qc.measure(qr, cr)
     qc.measure(qr_standalone, cr_standalone)
     qpy_file = io.BytesIO()
     dump(qc, qpy_file)
     qpy_file.seek(0)
     new_circ = load(qpy_file)[0]
     self.assertEqual(qc, new_circ)
Beispiel #12
0
def generate_register_edge_cases():
    """Generate register edge case circuits."""
    register_edge_cases = []
    # Circuit with shared bits in a register
    qubits = [Qubit() for _ in range(5)]
    shared_qc = QuantumCircuit()
    shared_qc.add_bits(qubits)
    shared_qr = QuantumRegister(bits=qubits)
    shared_qc.add_register(shared_qr)
    shared_qc.h(shared_qr)
    shared_qc.cx(0, 1)
    shared_qc.cx(0, 2)
    shared_qc.cx(0, 3)
    shared_qc.cx(0, 4)
    shared_qc.measure_all()
    register_edge_cases.append(shared_qc)
    # Circuit with registers that have a mix of standalone and shared register
    # bits
    qr = QuantumRegister(5, "foo")
    qr = QuantumRegister(name="bar", bits=qr[:3] + [Qubit(), Qubit()])
    cr = ClassicalRegister(5, "foo")
    cr = ClassicalRegister(name="classical_bar",
                           bits=cr[:3] + [Clbit(), Clbit()])
    hybrid_qc = QuantumCircuit(qr, cr)
    hybrid_qc.h(0)
    hybrid_qc.cx(0, 1)
    hybrid_qc.cx(0, 2)
    hybrid_qc.cx(0, 3)
    hybrid_qc.cx(0, 4)
    hybrid_qc.measure(qr, cr)
    register_edge_cases.append(hybrid_qc)
    # Circuit with mixed standalone and shared registers
    qubits = [Qubit() for _ in range(5)]
    clbits = [Clbit() for _ in range(5)]
    mixed_qc = QuantumCircuit()
    mixed_qc.add_bits(qubits)
    mixed_qc.add_bits(clbits)
    qr = QuantumRegister(bits=qubits)
    cr = ClassicalRegister(bits=clbits)
    mixed_qc.add_register(qr)
    mixed_qc.add_register(cr)
    qr_standalone = QuantumRegister(2, "standalone")
    mixed_qc.add_register(qr_standalone)
    cr_standalone = ClassicalRegister(2, "classical_standalone")
    mixed_qc.add_register(cr_standalone)
    mixed_qc.unitary(random_unitary(32, seed=42), qr)
    mixed_qc.unitary(random_unitary(4, seed=100), qr_standalone)
    mixed_qc.measure(qr, cr)
    mixed_qc.measure(qr_standalone, cr_standalone)
    register_edge_cases.append(mixed_qc)
    # Circuit with out of order register bits
    qr_standalone = QuantumRegister(2, "standalone")
    qubits = [Qubit() for _ in range(5)]
    clbits = [Clbit() for _ in range(5)]
    ooo_qc = QuantumCircuit()
    ooo_qc.add_bits(qubits)
    ooo_qc.add_bits(clbits)
    random.seed(42)
    random.shuffle(qubits)
    random.shuffle(clbits)
    qr = QuantumRegister(bits=qubits)
    cr = ClassicalRegister(bits=clbits)
    ooo_qc.add_register(qr)
    ooo_qc.add_register(cr)
    qr_standalone = QuantumRegister(2, "standalone")
    cr_standalone = ClassicalRegister(2, "classical_standalone")
    ooo_qc.add_bits([qr_standalone[1], qr_standalone[0]])
    ooo_qc.add_bits([cr_standalone[1], cr_standalone[0]])
    ooo_qc.add_register(qr_standalone)
    ooo_qc.add_register(cr_standalone)
    ooo_qc.unitary(random_unitary(32, seed=42), qr)
    ooo_qc.unitary(random_unitary(4, seed=100), qr_standalone)
    ooo_qc.measure(qr, cr)
    ooo_qc.measure(qr_standalone, cr_standalone)
    register_edge_cases.append(ooo_qc)
    return register_edge_cases
def _read_circuit(file_obj):
    header, name, metadata = _read_header(file_obj)
    (
        name_size,  # pylint: disable=unused-variable
        global_phase,
        num_qubits,
        num_clbits,
        metadata_size,  # pylint: disable=unused-variable
        num_registers,
        num_instructions,
    ) = header
    out_registers = {"q": {}, "c": {}}
    if num_registers > 0:
        circ = QuantumCircuit(name=name,
                              global_phase=global_phase,
                              metadata=metadata)
        registers = _read_registers(file_obj, num_registers)

        for bit_type_label, bit_type, reg_type in [
            ("q", Qubit, QuantumRegister),
            ("c", Clbit, ClassicalRegister),
        ]:
            register_bits = set()
            # Add quantum registers and bits
            for register_name in registers[bit_type_label]:
                standalone, indices = registers[bit_type_label][register_name]
                if standalone:
                    start = min(indices)
                    count = start
                    out_of_order = False
                    for index in indices:
                        if not out_of_order and index != count:
                            out_of_order = True
                        count += 1
                        if index in register_bits:
                            raise QiskitError("Duplicate register bits found")
                        register_bits.add(index)

                    num_reg_bits = len(indices)
                    # Create a standlone register of the appropriate length (from
                    # the number of indices in the qpy data) and add it to the circuit
                    reg = reg_type(num_reg_bits, register_name)
                    # If any bits from qreg are out of order in the circuit handle
                    # is case
                    if out_of_order:
                        sorted_indices = np.argsort(indices)
                        for index in sorted_indices:
                            pos = indices[index]
                            if bit_type_label == "q":
                                bit_len = len(circ.qubits)
                            else:
                                bit_len = len(circ.clbits)
                            # Fill any holes between the current register bit and the
                            # next one
                            if pos > bit_len:
                                bits = [
                                    bit_type() for _ in range(pos - bit_len)
                                ]
                                circ.add_bits(bits)
                            circ.add_bits([reg[index]])
                        circ.add_register(reg)
                    else:
                        if bit_type_label == "q":
                            bit_len = len(circ.qubits)
                        else:
                            bit_len = len(circ.clbits)
                        # If there is a hole between the start of the register and the
                        # current bits and standalone bits to fill the gap.
                        if start > len(circ.qubits):
                            bits = [bit_type() for _ in range(start - bit_len)]
                            circ.add_bits(bit_len)
                        circ.add_register(reg)
                        out_registers[bit_type_label][register_name] = reg
                else:
                    for index in indices:
                        if bit_type_label == "q":
                            bit_len = len(circ.qubits)
                        else:
                            bit_len = len(circ.clbits)
                        # Add any missing bits
                        bits = [bit_type() for _ in range(index + 1 - bit_len)]
                        circ.add_bits(bits)
                        if index in register_bits:
                            raise QiskitError("Duplicate register bits found")
                        register_bits.add(index)
                    if bit_type_label == "q":
                        bits = [circ.qubits[i] for i in indices]
                    else:
                        bits = [circ.clbits[i] for i in indices]
                    reg = reg_type(name=register_name, bits=bits)
                    circ.add_register(reg)
                    out_registers[bit_type_label][register_name] = reg
        # If we don't have sufficient bits in the circuit after adding
        # all the registers add more bits to fill the circuit
        if len(circ.qubits) < num_qubits:
            qubits = [Qubit() for _ in range(num_qubits - len(circ.qubits))]
            circ.add_bits(qubits)
        if len(circ.clbits) < num_clbits:
            clbits = [Clbit() for _ in range(num_qubits - len(circ.clbits))]
            circ.add_bits(clbits)
    else:
        circ = QuantumCircuit(
            num_qubits,
            num_clbits,
            name=name,
            global_phase=global_phase,
            metadata=metadata,
        )
    custom_instructions = _read_custom_instructions(file_obj)
    for _instruction in range(num_instructions):
        _read_instruction(file_obj, circ, out_registers, custom_instructions)

    return circ
Beispiel #14
0
def read_circuit(file_obj, version):
    """Read a single QuantumCircuit object from the file like object.

    Args:
        file_obj (FILE): The file like object to read the circuit data from.
        version (int): QPY version.

    Returns:
        QuantumCircuit: The circuit object from the file.

    Raises:
        QpyError: Invalid register.
    """
    vectors = {}
    if version < 2:
        header, name, metadata = _read_header(file_obj)
    else:
        header, name, metadata = _read_header_v2(file_obj, version, vectors)

    global_phase = header["global_phase"]
    num_qubits = header["num_qubits"]
    num_clbits = header["num_clbits"]
    num_registers = header["num_registers"]
    num_instructions = header["num_instructions"]
    out_registers = {"q": {}, "c": {}}
    if num_registers > 0:
        circ = QuantumCircuit(name=name,
                              global_phase=global_phase,
                              metadata=metadata)
        if version < 4:
            registers = _read_registers(file_obj, num_registers)
        else:
            registers = _read_registers_v4(file_obj, num_registers)

        for bit_type_label, bit_type, reg_type in [
            ("q", Qubit, QuantumRegister),
            ("c", Clbit, ClassicalRegister),
        ]:
            register_bits = set()
            # Add quantum registers and bits
            for register_name in registers[bit_type_label]:
                standalone, indices, in_circuit = registers[bit_type_label][
                    register_name]
                indices_defined = [x for x in indices if x >= 0]
                # If a register has no bits in the circuit skip it
                if not indices_defined:
                    continue
                if standalone:
                    start = min(indices_defined)
                    count = start
                    out_of_order = False
                    for index in indices:
                        if index < 0:
                            out_of_order = True
                            continue
                        if not out_of_order and index != count:
                            out_of_order = True
                        count += 1
                        if index in register_bits:
                            # If we have a bit in the position already it's been
                            # added by an earlier register in the circuit
                            # otherwise it's invalid qpy
                            if not in_circuit:
                                continue
                            raise exceptions.QpyError(
                                "Duplicate register bits found")

                        register_bits.add(index)

                    num_reg_bits = len(indices)
                    # Create a standlone register of the appropriate length (from
                    # the number of indices in the qpy data) and add it to the circuit
                    reg = reg_type(num_reg_bits, register_name)
                    # If any bits from qreg are out of order in the circuit handle
                    # is case
                    if out_of_order or not in_circuit:
                        for index, pos in sorted(enumerate(x for x in indices
                                                           if x >= 0),
                                                 key=lambda x: x[1]):
                            if bit_type_label == "q":
                                bit_len = len(circ.qubits)
                            else:
                                bit_len = len(circ.clbits)
                            if pos < bit_len:
                                # If we have a bit in the position already it's been
                                # added by an earlier register in the circuit
                                # otherwise it's invalid qpy
                                if not in_circuit:
                                    continue
                                raise exceptions.QpyError(
                                    "Duplicate register bits found")
                            # Fill any holes between the current register bit and the
                            # next one
                            if pos > bit_len:
                                bits = [
                                    bit_type() for _ in range(pos - bit_len)
                                ]
                                circ.add_bits(bits)
                            circ.add_bits([reg[index]])
                        if in_circuit:
                            circ.add_register(reg)
                    else:
                        if bit_type_label == "q":
                            bit_len = len(circ.qubits)
                        else:
                            bit_len = len(circ.clbits)
                        # If there is a hole between the start of the register and the
                        # current bits and standalone bits to fill the gap.
                        if start > len(circ.qubits):
                            bits = [bit_type() for _ in range(start - bit_len)]
                            circ.add_bits(bit_len)
                        if in_circuit:
                            circ.add_register(reg)
                        out_registers[bit_type_label][register_name] = reg
                else:
                    for index in indices:
                        if bit_type_label == "q":
                            bit_len = len(circ.qubits)
                        else:
                            bit_len = len(circ.clbits)
                        # Add any missing bits
                        bits = [bit_type() for _ in range(index + 1 - bit_len)]
                        circ.add_bits(bits)
                        if index in register_bits:
                            raise exceptions.QpyError(
                                "Duplicate register bits found")
                        register_bits.add(index)
                    if bit_type_label == "q":
                        bits = [circ.qubits[i] for i in indices]
                    else:
                        bits = [circ.clbits[i] for i in indices]
                    reg = reg_type(name=register_name, bits=bits)
                    if in_circuit:
                        circ.add_register(reg)
                    out_registers[bit_type_label][register_name] = reg
        # If we don't have sufficient bits in the circuit after adding
        # all the registers add more bits to fill the circuit
        if len(circ.qubits) < num_qubits:
            qubits = [Qubit() for _ in range(num_qubits - len(circ.qubits))]
            circ.add_bits(qubits)
        if len(circ.clbits) < num_clbits:
            clbits = [Clbit() for _ in range(num_qubits - len(circ.clbits))]
            circ.add_bits(clbits)
    else:
        circ = QuantumCircuit(
            num_qubits,
            num_clbits,
            name=name,
            global_phase=global_phase,
            metadata=metadata,
        )
    custom_instructions = _read_custom_instructions(file_obj, version, vectors)
    for _instruction in range(num_instructions):
        _read_instruction(file_obj, circ, out_registers, custom_instructions,
                          version, vectors)
    for vec_name, (vector, initialized_params) in vectors.items():
        if len(initialized_params) != len(vector):
            warnings.warn(
                f"The ParameterVector: '{vec_name}' is not fully identical to its "
                "pre-serialization state. Elements "
                f"{', '.join([str(x) for x in set(range(len(vector))) - initialized_params])} "
                "in the ParameterVector will be not equal to the pre-serialized ParameterVector "
                f"as they weren't used in the circuit: {circ.name}",
                UserWarning,
            )

    return circ
 def test_x_measurement(self):
     """this will give you something different every time,
      so don't try to test the exact answer"""
     a = GraphState(self.G)
     a.x_measurement(a.qreg[0], a.creg[0])
     assert isinstance(a.creg[0], type(Clbit(ClassicalRegister(3, 'c2'), 0)))