DAGCircuit
class qiskit.dagcircuit.DAGCircuit
Bases: object
Quantum circuit as a directed acyclic graph.
There are 3 types of nodes in the graph: inputs, outputs, and operations. The nodes are connected by directed edges that correspond to qubits and bits.
Create an empty circuit.
Attributes
calibrations
Return calibration dictionary.
The custom pulse definition of a given gate is of the form
{‘gate_name’: {(qubits, params): schedule}}
global_phase
Return the global phase of the circuit.
node_counter
Returns the number of nodes in the dag.
wires
Return a list of the wires in order.
Methods
add_calibration
add_calibration(gate, qubits, schedule, params=None)
Register a low-level, custom pulse definition for the given gate.
Parameters
- gate (Union[Gate, str]) – Gate information.
- qubits (Union[int, Tuple[int]]) – List of qubits to be measured.
- schedule (Schedule) – Schedule information.
- params (Optional[List[Union[float, Parameter]]]) – A list of parameters.
Raises
Exception – if the gate is of type string and params is None.
add_clbits
add_clbits(clbits)
Add individual clbit wires.
add_creg
add_creg(creg)
Add all wires in a classical register.
add_qreg
add_qreg(qreg)
Add all wires in a quantum register.
add_qubits
add_qubits(qubits)
Add individual qubit wires.
ancestors
ancestors(node)
Returns set of the ancestors of a node as DAGOpNodes and DAGInNodes.
apply_operation_back
apply_operation_back(op, qargs=(), cargs=(), *, check=True)
Apply an operation to the output of the circuit.
Parameters
- op (qiskit.circuit.Operation) – the operation associated with the DAG node
- qargs (tuple[Qubit]) – qubits that op will be applied to
- cargs (tuple[Clbit]) – cbits that op will be applied to
- check (bool) – If
True
(default), this function will enforce that theDAGCircuit
data-structure invariants are maintained (allqargs
areQubit
s, all are in the DAG, etc). IfFalse
, the caller must uphold these invariants itself, but the cost of several checks will be skipped. This is most useful when building a new DAG from a source of known-good nodes.
Returns
the node for the op that was added to the dag
Return type
Raises
DAGCircuitError – if a leaf node is connected to multiple outputs
apply_operation_front
apply_operation_front(op, qargs=(), cargs=(), *, check=True)
Apply an operation to the input of the circuit.
Parameters
- op (qiskit.circuit.Operation) – the operation associated with the DAG node
- qargs (tuple[Qubit]) – qubits that op will be applied to
- cargs (tuple[Clbit]) – cbits that op will be applied to
- check (bool) – If
True
(default), this function will enforce that theDAGCircuit
data-structure invariants are maintained (allqargs
areQubit
s, all are in the DAG, etc). IfFalse
, the caller must uphold these invariants itself, but the cost of several checks will be skipped. This is most useful when building a new DAG from a source of known-good nodes.
Returns
the node for the op that was added to the dag
Return type
Raises
DAGCircuitError – if initial nodes connected to multiple out edges
bfs_successors
bfs_successors(node)
Returns an iterator of tuples of (DAGNode, [DAGNodes]) where the DAGNode is the current node and [DAGNode] is its successors in BFS order.
classical_predecessors
classical_predecessors(node)
Returns iterator of the predecessors of a node that are connected by a classical edge as DAGOpNodes and DAGInNodes.
classical_successors
classical_successors(node)
Returns iterator of the successors of a node that are connected by a classical edge as DAGOpNodes and DAGInNodes.
collect_1q_runs
collect_1q_runs()
Return a set of non-conditional runs of 1q “op” nodes.
collect_2q_runs
collect_2q_runs()
Return a set of non-conditional runs of 2q “op” nodes.
collect_runs
collect_runs(namelist)
Return a set of non-conditional runs of “op” nodes with the given names.
For example, “… h q[0]; cx q[0],q[1]; cx q[0],q[1]; h q[1]; ..” would produce the tuple of cx nodes as an element of the set returned from a call to collect_runs([“cx”]). If instead the cx nodes were “cx q[0],q[1]; cx q[1],q[0];”, the method would still return the pair in a tuple. The namelist can contain names that are not in the circuit’s basis.
Nodes must have only one successor to continue the run.
compose
compose(other, qubits=None, clbits=None, front=False, inplace=True)
Compose the other
circuit onto the output of this circuit.
A subset of input wires of other
are mapped to a subset of output wires of this circuit.
other
can be narrower or of equal width to self
.
Parameters
- other (DAGCircuit) – circuit to compose with self
- qubits (list[Qubit|int]) – qubits of self to compose onto.
- clbits (list[Clbit|int]) – clbits of self to compose onto.
- front (bool) – If True, front composition will be performed (not implemented yet)
- inplace (bool) – If True, modify the object. Otherwise return composed circuit.
Returns
the composed dag (returns None if inplace==True).
Return type
Raises
DAGCircuitError – if other
is wider or there are duplicate edge mappings.
copy_empty_like
copy_empty_like()
Return a copy of self with the same structure but empty.
That structure includes:
- name and other metadata
- global phase
- duration
- all the qubits and clbits, including the registers.
Returns
An empty copy of self.
Return type
count_ops
count_ops(*, recurse=True)
Count the occurrences of operation names.
Parameters
recurse (bool) – if True
(default), then recurse into control-flow operations. In all cases, this counts only the number of times the operation appears in any possible block; both branches of if-elses are counted, and for- and while-loop blocks are only counted once.
Returns
a mapping of operation names to the number of times it appears.
Return type
count_ops_longest_path
count_ops_longest_path()
Count the occurrences of operation names on the longest path.
Returns a dictionary of counts keyed on the operation name.
depth
depth(*, recurse=False)
Return the circuit depth. If there is control flow present, this count may only be an estimate, as the complete control-flow path cannot be statically known.
Parameters
recurse (bool) – if True
, then recurse into control-flow operations. For loops with known-length iterators are counted as if the loop had been manually unrolled (i.e. with each iteration of the loop body written out explicitly). If-else blocks take the longer case of the two branches. While loops are counted as if the loop body runs once only. Defaults to False
and raises DAGCircuitError
if any control flow is present, to avoid silently returning a nonsensical number.
Returns
the circuit depth
Return type
Raises
- DAGCircuitError – if not a directed acyclic graph
- DAGCircuitError – if unknown control flow is present in a recursive call, or any control flow is present in a non-recursive call.
descendants
descendants(node)
Returns set of the descendants of a node as DAGOpNodes and DAGOutNodes.
draw
draw(scale=0.7, filename=None, style='color')
Draws the dag circuit.
This function needs Graphviz to be installed. Graphviz is not a python package and can’t be pip installed (the graphviz
package on PyPI is a Python interface library for Graphviz and does not actually install Graphviz). You can refer to the Graphviz documentation on how to install it.
Parameters
- scale (float) – scaling factor
- filename (str) – file path to save image to (format inferred from name)
- style (str) – ‘plain’: B&W graph; ‘color’ (default): color input/output/op nodes
Returns
if in Jupyter notebook and not saving to file, otherwise None.
Return type
Ipython.display.Image
edges
edges(nodes=None)
Iterator for edge values and source and dest node
This works by returning the output edges from the specified nodes. If no nodes are specified all edges from the graph are returned.
Parameters
nodes (DAGOpNode, DAGInNode, or DAGOutNode|list(DAGOpNode, DAGInNode, or DAGOutNode) – Either a list of nodes or a single input node. If none is specified, all edges are returned from the graph.
Yields
edge –
the edge in the same format as out_edges the tuple
(source node, destination node, edge data)
find_bit
find_bit(bit)
Finds locations in the circuit, by mapping the Qubit and Clbit to positional index BitLocations is defined as: BitLocations = namedtuple(“BitLocations”, (“index”, “registers”))
Parameters
bit (Bit) – The bit to locate.
Returns
A 2-tuple. The first element (index
)
contains the index at which the Bit
can be found (in either qubits
, clbits
, depending on its type). The second element (registers
) is a list of (register, index)
pairs with an entry for each Register
in the circuit which contains the Bit
(and the index in the Register
at which it can be found).
Return type
namedtuple(int, List[Tuple(Register, int)])
Raises:
DAGCircuitError: If the supplied Bit
was of an unknown type. DAGCircuitError: If the supplied Bit
could not be found on the circuit.
front_layer
front_layer()
Return a list of op nodes in the first layer of this dag.
gate_nodes
gate_nodes()
Get the list of gate nodes in the dag.
Returns
the list of DAGOpNodes that represent gates.
Return type
has_calibration_for
has_calibration_for(node)
Return True if the dag has a calibration defined for the node operation. In this case, the operation does not need to be translated to the device basis.
idle_wires
idle_wires(ignore=None)
Return idle wires.
Parameters
ignore (list(str)) – List of node names to ignore. Default: []
Yields
Bit – Bit in idle wire.
Raises
DAGCircuitError – If the DAG is invalid
is_predecessor
is_predecessor(node, node_pred)
Checks if a second node is in the predecessors of node.
is_successor
is_successor(node, node_succ)
Checks if a second node is in the successors of node.
layers
layers()
Yield a shallow view on a layer of this DAGCircuit for all d layers of this circuit.
A layer is a circuit whose gates act on disjoint qubits, i.e., a layer has depth 1. The total number of layers equals the circuit depth d. The layers are indexed from 0 to d-1 with the earliest layer at index 0. The layers are constructed using a greedy algorithm. Each returned layer is a dict containing {“graph”: circuit graph, “partition”: list of qubit lists}.
The returned layer contains new (but semantically equivalent) DAGOpNodes, DAGInNodes, and DAGOutNodes. These are not the same as nodes of the original dag, but are equivalent via DAGNode.semantic_eq(node1, node2).
TODO: Gates that use the same cbits will end up in different layers as this is currently implemented. This may not be the desired behavior.
longest_path
longest_path()
Returns the longest path in the dag as a list of DAGOpNodes, DAGInNodes, and DAGOutNodes.
multi_qubit_ops
multi_qubit_ops()
Get list of 3+ qubit operations. Ignore directives like snapshot and barrier.
multigraph_layers
multigraph_layers()
Yield layers of the multigraph.
named_nodes
named_nodes(*names)
Get the set of “op” nodes with the given name.
node
node(node_id)
Get the node in the dag.
Parameters
node_id (int) – Node identifier.
Returns
the node.
Return type
node
nodes
nodes()
Iterator for node values.
Yields
node – the node.
nodes_on_wire
nodes_on_wire(wire, only_ops=False)
Iterator for nodes that affect a given wire.
Parameters
- wire (Bit) – the wire to be looked at.
- only_ops (bool) – True if only the ops nodes are wanted; otherwise, all nodes are returned.
Yields
Iterator – the successive nodes on the given wire
Raises
DAGCircuitError – if the given wire doesn’t exist in the DAG
num_clbits
num_clbits()
Return the total number of classical bits used by the circuit.
num_qubits
num_qubits()
Return the total number of qubits used by the circuit. num_qubits() replaces former use of width(). DAGCircuit.width() now returns qubits + clbits for consistency with Circuit.width() [qiskit-terra #2564].
num_tensor_factors
num_tensor_factors()
Compute how many components the circuit can decompose into.
op_nodes
op_nodes(op=None, include_directives=True)
Get the list of “op” nodes in the dag.
Parameters
- op (Type) –
qiskit.circuit.Operation
subclass op nodes to return. If None, return all op nodes. - include_directives (bool) – include barrier, snapshot etc.
Returns
the list of node ids containing the given op.
Return type
predecessors
predecessors(node)
Returns iterator of the predecessors of a node as DAGOpNodes and DAGInNodes.
properties
properties()
Return a dictionary of circuit properties.
quantum_causal_cone
quantum_causal_cone(qubit)
Returns causal cone of a qubit.
A qubit’s causal cone is the set of qubits that can influence the output of that qubit through interactions, whether through multi-qubit gates or operations. Knowing the causal cone of a qubit can be useful when debugging faulty circuits, as it can help identify which wire(s) may be causing the problem.
This method does not consider any classical data dependency in the DAGCircuit
, classical bit wires are ignored for the purposes of building the causal cone.
Parameters
qubit (Qubit) – The output qubit for which we want to find the causal cone.
Returns
The set of qubits whose interactions affect qubit
.
Return type
Set[Qubit]
quantum_predecessors
quantum_predecessors(node)
Returns iterator of the predecessors of a node that are connected by a quantum edge as DAGOpNodes and DAGInNodes.
quantum_successors
quantum_successors(node)
Returns iterator of the successors of a node that are connected by a quantum edge as Opnodes and DAGOutNodes.
remove_all_ops_named
remove_all_ops_named(opname)
Remove all operation nodes with the given name.
remove_ancestors_of
remove_ancestors_of(node)
Remove all of the ancestor operation nodes of node.
remove_clbits
remove_clbits(*clbits)
Remove classical bits from the circuit. All bits MUST be idle. Any registers with references to at least one of the specified bits will also be removed.
Parameters
clbits (List[Clbit]) – The bits to remove.
Raises
DAGCircuitError – a clbit is not a Clbit
, is not in the circuit, or is not idle.
remove_cregs
remove_cregs(*cregs)
Remove classical registers from the circuit, leaving underlying bits in place.
Raises
- DAGCircuitError – a creg is not a ClassicalRegister, or is not in
- the circuit. –
remove_descendants_of
remove_descendants_of(node)
Remove all of the descendant operation nodes of node.
remove_nonancestors_of
remove_nonancestors_of(node)
Remove all of the non-ancestors operation nodes of node.
remove_nondescendants_of
remove_nondescendants_of(node)
Remove all of the non-descendants operation nodes of node.
remove_op_node
remove_op_node(node)
Remove an operation node n.
Add edges from predecessors to successors.
remove_qregs
remove_qregs(*qregs)
Remove quantum registers from the circuit, leaving underlying bits in place.
Raises
- DAGCircuitError – a qreg is not a QuantumRegister, or is not in
- the circuit. –
remove_qubits
remove_qubits(*qubits)
Remove quantum bits from the circuit. All bits MUST be idle. Any registers with references to at least one of the specified bits will also be removed.
Parameters
qubits (List[Qubit]) – The bits to remove.
Raises
DAGCircuitError – a qubit is not a Qubit
, is not in the circuit, or is not idle.
replace_block_with_op
replace_block_with_op(node_block, op, wire_pos_map, cycle_check=True)
Replace a block of nodes with a single node.
This is used to consolidate a block of DAGOpNodes into a single operation. A typical example is a block of gates being consolidated into a single UnitaryGate
representing the unitary matrix of the block.
Parameters
- node_block (List[DAGNode]) – A list of dag nodes that represents the node block to be replaced
- op (qiskit.circuit.Operation) – The operation to replace the block with
- wire_pos_map (Dict[Bit, int]) – The dictionary mapping the bits to their positions in the output
qargs
orcargs
. This is necessary to reconstruct the arg order over multiple gates in the combined single op node. If aBit
is not in the dictionary, it will not be added to the args; this can be useful when dealing with control-flow operations that have inherent bits in theircondition
ortarget
fields. - cycle_check (bool) – When set to True this method will check that replacing the provided
node_block
with a single node would introduce a cycle (which would invalidate theDAGCircuit
) and will raise aDAGCircuitError
if a cycle would be introduced. This checking comes with a run time penalty. If you can guarantee that your inputnode_block
is a contiguous block and won’t introduce a cycle when it’s contracted to a single node, this can be set toFalse
to improve the runtime performance of this method.
Raises
DAGCircuitError – if cycle_check
is set to True
and replacing the specified block introduces a cycle or if node_block
is empty.
Returns
The op node that replaces the block.
Return type
reverse_ops
reverse_ops()
Reverse the operations in the self
circuit.
Returns
the reversed dag.
Return type
separable_circuits
separable_circuits(remove_idle_qubits=False)
Decompose the circuit into sets of qubits with no gates connecting them.
Parameters
remove_idle_qubits (bool) – Flag denoting whether to remove idle qubits from the separated circuits. If False
, each output circuit will contain the same number of qubits as self
.
Returns
The circuits resulting from separating self
into sets
of disconnected qubits
Return type
List[DAGCircuit]
Each DAGCircuit
instance returned by this method will contain the same number of clbits as self
. The global phase information in self
will not be maintained in the subcircuits returned by this method.
serial_layers
serial_layers()
Yield a layer for all gates of this circuit.
A serial layer is a circuit with one gate. The layers have the same structure as in layers().
size
size(*, recurse=False)
Return the number of operations. If there is control flow present, this count may only be an estimate, as the complete control-flow path cannot be statically known.
Parameters
recurse (bool) – if True
, then recurse into control-flow operations. For loops with known-length iterators are counted unrolled. If-else blocks sum both of the two branches. While loops are counted as if the loop body runs once only. Defaults to False
and raises DAGCircuitError
if any control flow is present, to avoid silently returning a mostly meaningless number.
Returns
the circuit size
Return type
Raises
DAGCircuitError – if an unknown ControlFlowOp
is present in a call with recurse=True
, or any control flow is present in a non-recursive call.
substitute_node
substitute_node(node, op, inplace=False, propagate_condition=True)
Replace an DAGOpNode with a single operation. qargs, cargs and conditions for the new operation will be inferred from the node to be replaced. The new operation will be checked to match the shape of the replaced operation.
Parameters
- node (DAGOpNode) – Node to be replaced
- op (qiskit.circuit.Operation) – The
qiskit.circuit.Operation
instance to be added to the DAG - inplace (bool) – Optional, default False. If True, existing DAG node will be modified to include op. Otherwise, a new DAG node will be used.
- propagate_condition (bool) – Optional, default True. If True, a condition on the
node
to be replaced will be applied to the newop
. This is the legacy behaviour. If either node is a control-flow operation, this will be ignored. If theop
already has a condition,DAGCircuitError
is raised.
Returns
the new node containing the added operation.
Return type
Raises
- DAGCircuitError – If replacement operation was incompatible with
- location** of **target node. –
substitute_node_with_dag
substitute_node_with_dag(node, input_dag, wires=None, propagate_condition=True)
Replace one node with dag.
Parameters
- node (DAGOpNode) – node to substitute
- input_dag (DAGCircuit) – circuit that will substitute the node
- wires (list[Bit] | Dict[Bit, Bit]) – gives an order for (qu)bits in the input circuit. If a list, then the bits refer to those in the
input_dag
, and the order gets matched to the node wires by qargs first, then cargs, then conditions. If a dictionary, then a mapping of bits in theinput_dag
to those that thenode
acts on. - propagate_condition (bool) – If
True
(default), then anycondition
attribute on the operation withinnode
is propagated to each node in theinput_dag
. IfFalse
, then theinput_dag
is assumed to faithfully implement suitable conditional logic already. This is ignored forControlFlowOp
s (i.e. treated as if it isFalse
); replacements of those must already fulfil the same conditional logic or this function would be close to useless for them.
Returns
maps node IDs from input_dag to their new node incarnations in self.
Return type
Raises
DAGCircuitError – if met with unexpected predecessor/successors
successors
successors(node)
Returns iterator of the successors of a node as DAGOpNodes and DAGOutNodes.
swap_nodes
swap_nodes(node1, node2)
Swap connected nodes e.g. due to commutation.
Parameters
- node1 (OpNode) – predecessor node
- node2 (OpNode) – successor node
Raises
DAGCircuitError – if either node is not an OpNode or nodes are not connected
topological_nodes
topological_nodes(key=None)
Yield nodes in topological order.
Parameters
key (Callable) – A callable which will take a DAGNode object and return a string sort key. If not specified the sort_key
attribute will be used as the sort key for each node.
Returns
node in topological order
Return type
generator(DAGOpNode, DAGInNode, or DAGOutNode)
topological_op_nodes
topological_op_nodes(key=None)
Yield op nodes in topological order.
Allowed to pass in specific key to break ties in top order
Parameters
key (Callable) – A callable which will take a DAGNode object and return a string sort key. If not specified the sort_key
attribute will be used as the sort key for each node.
Returns
op node in topological order
Return type
generator(DAGOpNode)
two_qubit_ops
two_qubit_ops()
Get list of 2 qubit operations. Ignore directives like snapshot and barrier.
width
width()
Return the total number of qubits + clbits used by the circuit. This function formerly returned the number of qubits by the calculation return len(self._wires) - self.num_clbits() but was changed by issue #2564 to return number of qubits + clbits with the new function DAGCircuit.num_qubits replacing the former semantic of DAGCircuit.width().