예제 #1
0
    def test_move_measurements(self):
        """Measurements applied AFTER swap mapping.
        """
        backend = FakeQX5BackEnd()
        cmap = backend.configuration().coupling_map
        circ = QuantumCircuit.from_qasm_file(
            self._get_resource_path('qasm/move_measurements.qasm'))

        dag_circuit = DAGCircuit.fromQuantumCircuit(circ)
        lay = {
            ('qa', 0): ('q', 0),
            ('qa', 1): ('q', 1),
            ('qb', 0): ('q', 15),
            ('qb', 1): ('q', 2),
            ('qb', 2): ('q', 14),
            ('qN', 0): ('q', 3),
            ('qN', 1): ('q', 13),
            ('qN', 2): ('q', 4),
            ('qc', 0): ('q', 12),
            ('qNt', 0): ('q', 5),
            ('qNt', 1): ('q', 11),
            ('qt', 0): ('q', 6)
        }
        out_dag = transpile_dag(dag_circuit,
                                initial_layout=lay,
                                coupling_map=cmap,
                                format='dag')
        moved_meas = remove_last_measurements(out_dag, perform_remove=False)
        meas_nodes = out_dag.get_named_nodes('measure')
        self.assertEqual(len(moved_meas), len(meas_nodes))
예제 #2
0
    def test_optimize_1q_gates_collapse_identity(self):
        """test optimize_1q_gates removes u1(2*pi) rotations.

        See: https://github.com/Qiskit/qiskit-terra/issues/159
        """
        qr = QuantumRegister(2, 'qr')
        cr = ClassicalRegister(2, 'cr')
        qc = QuantumCircuit(qr, cr)
        qc.h(qr[0])
        qc.cx(qr[1], qr[0])
        qc.u1(2 * sympy.pi,
              qr[0])  # TODO: this identity should be removed (but is not)
        qc.cx(qr[1], qr[0])
        qc.u1(sympy.pi / 2, qr[0])  # these three should combine
        qc.u1(sympy.pi, qr[0])  # to identity then
        qc.u1(sympy.pi / 2, qr[0])  # optimized away.
        qc.cx(qr[1], qr[0])
        qc.u1(np.pi, qr[1])  # this doesn't become precisely 0, so should
        qc.u1(np.pi,
              qr[1])  # combine but stay, until an approximate optimizer.
        qc.measure(qr[0], cr[0])
        qc.measure(qr[1], cr[1])

        dag = DAGCircuit.fromQuantumCircuit(qc)
        simplified_dag = mapper.optimize_1q_gates(dag)
        num_u1_gates_remaining = len(simplified_dag.get_named_nodes('u1'))
        self.assertEqual(num_u1_gates_remaining, 2)
예제 #3
0
def circuit_to_dag(circuit):
    """Build a ``DAGCircuit`` object from a ``QuantumCircuit``.

    Args:
        circuit (QuantumCircuit): the input circuit.

    Return:
        DAGCircuit: the DAG representing the input circuit.
    """
    dagcircuit = DAGCircuit()
    dagcircuit.name = circuit.name
    for register in circuit.qregs:
        dagcircuit.add_qreg(register)
    for register in circuit.cregs:
        dagcircuit.add_creg(register)

    for main_instruction in circuit.data:
        # TODO: generate nodes for CompositeGates;
        # for now simply drop their instructions into the DAG
        instruction_list = []
        is_composite = isinstance(main_instruction, CompositeGate)
        if is_composite:
            instruction_list = main_instruction.instruction_list()
        else:
            instruction_list.append(main_instruction)

        for instruction in instruction_list:
            # Get arguments for classical control (if any)
            if instruction.control is None:
                control = None
            else:
                control = (instruction.control[0], instruction.control[1])

            def duplicate_instruction(inst):
                """Create a fresh instruction from an input instruction."""
                if inst.name == 'barrier':
                    params = [inst.qargs]
                elif inst.name == 'snapshot':
                    params = inst.params + [inst.qargs]
                else:
                    params = inst.params + inst.qargs + inst.cargs
                new_inst = inst.__class__(*params)
                return new_inst

            inst = duplicate_instruction(instruction)
            dagcircuit.apply_operation_back(inst, inst.qargs, inst.cargs,
                                            control)

    return dagcircuit
예제 #4
0
    def test_optimize_1q_gates_symbolic(self):
        """optimizes single qubit gate sequences with symbolic params.

        See: https://github.com/Qiskit/qiskit-terra/issues/172
        """
        qr = QuantumRegister(4)
        cr = ClassicalRegister(4)
        circ = QuantumCircuit(qr, cr)
        # unary
        circ.u1(-sympy.pi, qr[0])
        circ.u1(-sympy.pi / 2, qr[0])
        # binary
        circ.u1(0.2 * sympy.pi + 0.3 * sympy.pi, qr[1])
        circ.u1(1.3 - 0.3, qr[1])
        circ.u1(0.1 * sympy.pi / 2, qr[1])
        # extern
        circ.u1(sympy.sin(0.2 + 0.3 - sympy.pi), qr[2])
        # power
        circ.u1(sympy.pi, qr[3])
        circ.u1(0.3 + (-sympy.pi)**2, qr[3])

        dag = DAGCircuit.fromQuantumCircuit(circ)
        simplified_dag = mapper.optimize_1q_gates(dag)

        params = set()
        for n in simplified_dag.multi_graph.nodes:
            node = simplified_dag.multi_graph.node[n]
            if node['name'] == 'u1':
                params.add(node['op'].param[0])

        expected_params = {
            -3 * sympy.pi / 2, 1.0 + 0.55 * sympy.pi,
            sympy.N(-0.479425538604203), 0.3 + sympy.pi + sympy.pi**2
        }

        self.assertEqual(params, expected_params)
예제 #5
0
def circuit_to_dag(circuit):
    """Build a ``DAGCircuit`` object from a ``QuantumCircuit``.

    Args:
        circuit (QuantumCircuit): the input circuit.

    Return:
        DAGCircuit: the DAG representing the input circuit.
    """
    dagcircuit = DAGCircuit()
    dagcircuit.name = circuit.name
    for register in circuit.qregs:
        dagcircuit.add_qreg(register)
    for register in circuit.cregs:
        dagcircuit.add_creg(register)
    # Add user gate definitions
    for name, data in circuit.definitions.items():
        dagcircuit.add_basis_element(name, data["n_bits"], 0, data["n_args"])
        dagcircuit.add_gate_data(name, data)
    # Add instructions
    builtins = {
        "U": ["U", 1, 0, 3],
        "CX": ["CX", 2, 0, 0],
        "measure": ["measure", 1, 1, 0],
        "reset": ["reset", 1, 0, 0],
        "barrier": ["barrier", -1, 0, 0]
    }
    # Add simulator instructions
    simulator_instructions = {
        "snapshot": ["snapshot", -1, 0, 1],
        "save": ["save", -1, 0, 1],
        "load": ["load", -1, 0, 1],
        "noise": ["noise", -1, 0, 1]
    }

    for main_instruction in circuit.data:
        # TODO: generate definitions and nodes for CompositeGates,
        # for now simply drop their instructions into the DAG
        instruction_list = []
        is_composite = isinstance(main_instruction, CompositeGate)
        if is_composite:
            instruction_list = main_instruction.instruction_list()
        else:
            instruction_list.append(main_instruction)

        for instruction in instruction_list:
            # Add OpenQASM built-in gates on demand
            if instruction.name in builtins:
                dagcircuit.add_basis_element(*builtins[instruction.name])
            # Add simulator extension instructions
            if instruction.name in simulator_instructions:
                dagcircuit.add_basis_element(
                    *simulator_instructions[instruction.name])
            # Get arguments for classical control (if any)
            if instruction.control is None:
                control = None
            else:
                control = (instruction.control[0], instruction.control[1])

            def duplicate_instruction(inst):
                """Create a fresh instruction from an input instruction."""
                if inst.name == 'barrier':
                    params = [inst.qargs]
                elif inst.name in simulator_instructions.keys():
                    params = inst.params + [inst.qargs] + [inst.circuit]
                else:
                    params = inst.params + inst.qargs + inst.cargs
                new_inst = inst.__class__(*params)
                return new_inst

            inst = duplicate_instruction(instruction)
            dagcircuit.apply_operation_back(inst, inst.qargs, inst.cargs,
                                            control)

    return dagcircuit
예제 #6
0
def circuit_to_dag(circuit, expand_gates=True):
    """Build a ``DAGCircuit`` object from a ``QuantumCircuit``.

    Args:
        circuit (QuantumCircuit): the input circuit.
        expand_gates (bool): if ``False``, none of the gates are expanded,
            i.e. the gates that are defined in the circuit are included in
            the DAG basis.

    Return:
        DAGCircuit: the DAG representing the input circuit.
    """
    circuit = copy.deepcopy(circuit)

    dagcircuit = DAGCircuit()
    dagcircuit.name = circuit.name
    for register in circuit.qregs:
        dagcircuit.add_qreg(register)
    for register in circuit.cregs:
        dagcircuit.add_creg(register)
    # Add user gate definitions
    for name, data in circuit.definitions.items():
        dagcircuit.add_basis_element(name, data["n_bits"], 0, data["n_args"])
        dagcircuit.add_gate_data(name, data)
    # Add instructions
    builtins = {
        "U": ["U", 1, 0, 3],
        "CX": ["CX", 2, 0, 0],
        "measure": ["measure", 1, 1, 0],
        "reset": ["reset", 1, 0, 0],
        "barrier": ["barrier", -1, 0, 0]
    }
    # Add simulator instructions
    simulator_instructions = {
        "snapshot": ["snapshot", -1, 0, 1],
        "save": ["save", -1, 0, 1],
        "load": ["load", -1, 0, 1],
        "noise": ["noise", -1, 0, 1]
    }
    for main_instruction in circuit.data:
        # TODO: generate definitions and nodes for CompositeGates,
        # for now simply drop their instructions into the DAG
        instruction_list = []
        is_composite = isinstance(main_instruction, CompositeGate)
        if is_composite and expand_gates:
            instruction_list = main_instruction.instruction_list()
        else:
            instruction_list.append(main_instruction)

        for instruction in instruction_list:
            # Add OpenQASM built-in gates on demand
            if instruction.name in builtins:
                dagcircuit.add_basis_element(*builtins[instruction.name])
            # Add simulator extension instructions
            if instruction.name in simulator_instructions:
                dagcircuit.add_basis_element(
                    *simulator_instructions[instruction.name])
            # Get arguments for classical control (if any)
            if instruction.control is None:
                control = None
            else:
                control = (instruction.control[0], instruction.control[1])

            dagcircuit.apply_operation_back(instruction, instruction.qargs,
                                            instruction.cargs, control)

    return dagcircuit