def dagdependency_to_dag(dagdependency): """Build a ``DAGCircuit`` object from a ``DAGDependency``. Args: dag dependency (DAGDependency): the input dag. Return: DAGCircuit: the DAG representing the input circuit. """ dagcircuit = DAGCircuit() dagcircuit.name = dagdependency.name qregs = list(dagdependency.qregs.values()) cregs = list(dagdependency.cregs.values()) for register in qregs: dagcircuit.add_qreg(register) for register in cregs: dagcircuit.add_creg(register) for node in dagdependency.get_nodes(): # Get arguments for classical control (if any) inst = node.op.copy() inst.condition = node.condition dagcircuit.apply_operation_back(inst, node.qargs, node.cargs, inst.condition) return dagcircuit
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 instruction, qargs, cargs in circuit.data: # Get arguments for classical control (if any) if instruction.control is None: control = None else: control = (instruction.control[0], instruction.control[1]) instruction = copy.deepcopy(instruction) dagcircuit.apply_operation_back(instruction, qargs, cargs, control) return dagcircuit
def dagdependency_to_dag(dagdependency): """Build a ``DAGCircuit`` object from a ``DAGDependency``. Args: dag dependency (DAGDependency): the input dag. Return: DAGCircuit: the DAG representing the input circuit. """ dagcircuit = DAGCircuit() dagcircuit.name = dagdependency.name dagcircuit.metadata = dagdependency.metadata dagcircuit.add_qubits(dagdependency.qubits) dagcircuit.add_clbits(dagdependency.clbits) for register in dagdependency.qregs.values(): dagcircuit.add_qreg(register) for register in dagdependency.cregs.values(): dagcircuit.add_creg(register) for node in dagdependency.get_nodes(): # Get arguments for classical control (if any) inst = node.op.copy() dagcircuit.apply_operation_back(inst, node.qargs, node.cargs) # copy metadata dagcircuit.global_phase = dagdependency.global_phase dagcircuit.calibrations = dagdependency.calibrations return dagcircuit
def run(self, dag: DAGCircuit) -> DAGCircuit: """Run the Decompose pass on `dag`. Args: dag: input dag. Returns: output dag where ``gate`` was expanded. """ # Walk through the DAG and expand each non-basis node for node in dag.op_nodes(self.gate): # opaque or built-in gates are not decomposable if not node.op.definition: continue # TODO: allow choosing among multiple decomposition rules rule = node.op.definition if len(rule) == 1 and len(node.qargs) == len(rule[0][1]): dag.substitute_node(node, rule[0][0], inplace=True) else: # hacky way to build a dag on the same register as the rule is defined # TODO: need anonymous rules to address wires by index decomposition = DAGCircuit() qregs = {qb.register for inst in rule for qb in inst[1]} cregs = {cb.register for inst in rule for cb in inst[2]} for qreg in qregs: decomposition.add_qreg(qreg) for creg in cregs: decomposition.add_creg(creg) for inst in rule: decomposition.apply_operation_back(*inst) dag.substitute_node_with_dag(node, decomposition) return dag
def circuit_stripping(circuit,gates_to_strip): dag = circuit_to_dag(circuit) stripped_dag = DAGCircuit() [stripped_dag.add_qreg(x) for x in circuit.qregs] for vertex in dag.topological_op_nodes(): if vertex.op.name not in gates_to_strip: stripped_dag.apply_operation_back(op=vertex.op, qargs=vertex.qargs) return dag_to_circuit(stripped_dag)
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 instruction, qargs, cargs in circuit.data: # 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 issubclass(inst.__class__, inst_mod.Instruction) and inst.__class__ not in [ inst_mod.Instruction, gate.Gate]: if inst.name == 'barrier': new_inst = inst.__class__(inst.num_qubits) elif inst.name == 'initialize': params = getattr(inst, 'params', []) new_inst = inst.__class__(params) elif inst.name == 'snapshot': label = inst.params[0] snap_type = inst.params[1] new_inst = inst.__class__(inst.num_qubits, inst.num_clbits, label, snap_type) else: params = getattr(inst, 'params', []) new_inst = inst.__class__(*params) else: if isinstance(inst, gate.Gate): new_inst = gate.Gate(inst.name, inst.num_qubits, inst.params) else: new_inst = inst_mod.Instruction(name=inst.name, num_qubits=inst.num_qubits, num_clbits=inst.num_clbits, params=inst.params) new_inst.definition = inst.definition return new_inst dagcircuit.apply_operation_back(duplicate_instruction(instruction), qargs, cargs, control) return dagcircuit
def circuit_stripping(circuit): # Remove all single qubit gates and barriers in the circuit dag = circuit_to_dag(circuit) stripped_dag = DAGCircuit() [stripped_dag.add_qreg(x) for x in circuit.qregs] for vertex in dag.topological_op_nodes(): if len(vertex.qargs) == 2 and vertex.op.name!='barrier': stripped_dag.apply_operation_back(op=vertex.op, qargs=vertex.qargs) return dag_to_circuit(stripped_dag)
def tweedledum_to_qiskit_dag(circuit): qiskit_dag = DAGCircuit() qiskit_dag.add_qreg(circuit.num_qubits(), circuit.num_cbits()) for instruction in circuit: gate = _convert_tweedledum_op(instruction) qubits = [qubit.uid() for qubit in instruction.qubits()] cbits = [cbit.uid() for cbit in instruction.cbits()] qiskit_dag.apply_operation_back(gate, qubits, cbits) return qiskit_dag
def _to_dag(circuit): qiskit_dag = DAGCircuit() qreg = QuantumRegister(circuit.num_qubits()) qiskit_dag.add_qreg(qreg) if circuit.num_cbits(): creg = ClassicalRegister(circuit.num_cbits()) qiskit_dag.add_creg(creg) for instruction in circuit: gate = _convert_tweedledum_op(instruction) qubits = [qreg[qubit.uid()] for qubit in instruction.qubits()] cbits = [creg[cbit.uid()] for cbit in instruction.cbits()] qiskit_dag.apply_operation_back(gate, qubits, cbits) return qiskit_dag
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. Example: .. jupyter-execute:: from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.dagcircuit import DAGCircuit from qiskit.converters import circuit_to_dag from qiskit.visualization import dag_drawer %matplotlib inline q = QuantumRegister(3, 'q') c = ClassicalRegister(3, 'c') circ = QuantumCircuit(q, c) circ.h(q[0]) circ.cx(q[0], q[1]) circ.measure(q[0], c[0]) circ.rz(0.5, q[1]).c_if(c, 2) dag = circuit_to_dag(circ) dag_drawer(dag) """ dagcircuit = DAGCircuit() dagcircuit.name = circuit.name dagcircuit.global_phase = circuit.global_phase dagcircuit.calibrations = circuit.calibrations dagcircuit.metadata = circuit.metadata dagcircuit.add_qubits(circuit.qubits) dagcircuit.add_clbits(circuit.clbits) for register in circuit.qregs: dagcircuit.add_qreg(register) for register in circuit.cregs: dagcircuit.add_creg(register) for instruction in circuit.data: dagcircuit.apply_operation_back(instruction.operation.copy(), instruction.qubits, instruction.clbits) dagcircuit.duration = circuit.duration dagcircuit.unit = circuit.unit return dagcircuit
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 dag_stripping(dag, max_gates): ''' Remove all single qubit gates and barriers in the DAG Only leaves the first max_gates gates If max_gates is None, do all gates ''' stripped_dag = DAGCircuit() [stripped_dag.add_qreg(dag.qregs[qreg_name]) for qreg_name in dag.qregs] vertex_added = 0 for vertex in dag.topological_op_nodes(): within_gate_count = max_gates is None or vertex_added<max_gates if vertex.op.name!='barrier' and len(vertex.qargs)==2 and within_gate_count: stripped_dag.apply_operation_back(op=vertex.op, qargs=vertex.qargs) vertex_added += 1 return stripped_dag
def apply_back_to_dag_circuit( self, dag_circuit: DAGCircuit, initial_mapping: ty.Dict[Qubit, int], trans_mapping: ty.Dict[Qubit, int], ): reversed_trans_mapping = { val: key for key, val in trans_mapping.items() } for op in self._operations: logical_qubits = [initial_mapping[qubit] for qubit in op.qargs] new_physical_qubits = [ reversed_trans_mapping[qubit_index] for qubit_index in logical_qubits ] #print(new_physical_qubits) dag_circuit.apply_operation_back(op.op, new_physical_qubits, op.cargs, op.condition)
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 instruction, qargs, cargs in circuit.data: dagcircuit.apply_operation_back(instruction.copy(), qargs, cargs, instruction.condition) return dagcircuit
def apply(self, dag_circuit: DAGCircuit, front_layer: QuantumLayer, initial_mapping: ty.Dict[Qubit, int], trans_mapping: ty.Dict[Qubit, int]): dag_circuit.apply_operation_back(CXGate(), [self.left, self.middle]) dag_circuit.apply_operation_back(CXGate(), [self.middle, self.right]) dag_circuit.apply_operation_back(CXGate(), [self.left, self.middle]) dag_circuit.apply_operation_back(CXGate(), [self.middle, self.right]) # dag_circuit.apply_operation_back( # _BridgeGate(), [self.left, self.middle, self.right] # ) # Do not forget to remove the CNOT gate from self.left to self.right from the # front layer. op_to_remove: ty.Optional[DAGNode] = None for op in front_layer.ops: q1, q2 = initial_mapping[op.qargs[0]], initial_mapping[op.qargs[1]] if (len(op.qargs) == 2 and q1 == trans_mapping[self.left] and q2 == trans_mapping[self.right]): op_to_remove = op if op_to_remove is None: logger.warning( "Could not find a corresponding CNOT gate to remove with " "Bridge usage. Resulting circuit will likely be wrong.") else: front_layer.remove_operation(op_to_remove)
def apply(self, dag_circuit: DAGCircuit, front_layer: QuantumLayer, initial_mapping: ty.Dict[Qubit, int], trans_mapping: ty.Dict[Qubit, int]): dag_circuit.apply_operation_back(SwapGate(), [self.left, self.right])