-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DAGCircuit: Add get_causal_cone method #10325
Conversation
- Also added `get_qubit_input_node` and `get_qubit_output_node`.
Thank you for opening a new pull request. Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient. While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone. One or more of the the following people are requested to review this:
|
- Type checking was causing strange behavior during linting.
Pull Request Test Coverage Report for Build 5562839866
💛 - Coveralls |
- Replace lists with deque for the iteration.
Raynel Sanchez seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
826da16
to
7afeaca
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great start, thanks for getting it going. I left a few inline comments on some small cleanups you can make to the interface to make the implementation a bit simpler and also more consistent with the rest of the DAGCircuit API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fast updates, just a couple of small comments inline, mostly about doc formatting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is basically ready now, just a couple of small inline comments, but after that I think it's ready to merge
qiskit/dagcircuit/dagcircuit.py
Outdated
Returns: | ||
Set[Qubit]: The set of qubits whose interactions affect ``qubit``. | ||
""" | ||
# Retrieve the output node and the qubit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Retrieve the output node and the qubit | |
# Retrieve the output node from the qubit |
qiskit/dagcircuit/dagcircuit.py
Outdated
# Check if there are any qubits in common and that the operation is not a barrier. | ||
if ( | ||
len(qubit_set.intersection(qubits_to_check)) > 0 | ||
and not node_to_check.op.name == "barrier" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and not node_to_check.op.name == "barrier" | |
and node_to_check.op.name != "barrier" |
qiskit/dagcircuit/dagcircuit.py
Outdated
if ( | ||
len(qubit_set.intersection(qubits_to_check)) > 0 | ||
and not node_to_check.op.name == "barrier" | ||
): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably want to add a check on: not getattr(node_to_check.op, "_directive")
which is an expansion of the barrier check so it'll exclude other directives too, like snapshot from aer, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your code will already handle this correctly, but it'd be good to add a test that this function will include qubits in the causal cone that interact with the target qubit only via a classical condition.
For example,
qc = QuantumCircuit(2, 1)
qc.x(0)
qc.measure(0, 0)
qc.x(1).c_if(0, True)
In that circuit, qubit 0 is in the causal cone of qubit 1, but it never appears in a 2q quantum operation. I'm fairly sure your code already handles this right, but it'd be good to have the extra test.
Well, I just tried this with the code and it doesn't seem to handle it well. Since the controlled operation never happens directly in a multiqubit operation and the condition is happening based on a classical condition, it will ignore it as the function only considers qubits and not classical bits. This is an interesting test case though, and raises a great question of how direct do interactions have to be for it to be considered as part of the causal cone. In this case, since the output of qubit 0 affects the output of qubit 1, it should be part of its causal cone. I will try to work that into the code, thank you for bringing it up @jakelishman. |
Thinking about it, it actually gets very hairy very quickly, because with clbits there's a distinction between "writes" and "reads", which the qc = QuantumCircuit(3, 1) # Note the extra qubit
qc.x(0)
qc.measure(0, 0)
qc.x(1).c_if(0, True)
qc.x(2).c_if(0, True) Now the I'm not sure that it's going to be reasonable to handle this at the moment; the |
TBH, I'm thinking it might be better to call this |
qiskit/dagcircuit/dagcircuit.py
Outdated
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 classical to quantum influences through conditionals or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm finding this a bit hard to follow, maybe reword this a bit to something like?:
This method does not consider classical to quantum influences through conditionals or | |
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. |
qiskit/dagcircuit/dagcircuit.py
Outdated
qubits_to_check = qubits_to_check.union(qubit_set) | ||
# For each predecessor of the current node, filter input/output nodes, | ||
# also make sure it has at least one qubit in common. Then append. | ||
for node in self.predecessors(node_to_check): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to hold to the statement of ignoring the classical wires should we change this to?:
for node in self.predecessors(node_to_check): | |
for node in self.quantum_predecessors(node_to_check): |
(and above as well).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM now, thanks for all the quick updates.
# Add the qubit to the causal cone. | ||
qubits_to_check = {qubit} | ||
# Add predecessors of output node to the queue. | ||
queue = deque(self.predecessors(output_node)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be quantum predecessors too, but if the input is a Qubit
then there is no way that output_node
could have a classical wire into it.
Summary
The causal node of a qubit is the set of all the qubits that affect the resulting output of the aforementioned qubit. This PR aims to add the
get_causal_node
method toDAGCircuit
to obtain the causal node of a qubit in a circuit.A couple of helper methods have also been added:
get_qubit_input_node
: to get the input node of a certain qubit in the circuit.get_qubit_output_node
: to get the output node of a certain qubit in the circuit.Details and comments