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))
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)
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
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)
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
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