Skip to content
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

coupling_map.subgraph() creates extra nodes #6736

Closed
ajavadia opened this issue Jul 13, 2021 · 4 comments · Fixed by #6738
Closed

coupling_map.subgraph() creates extra nodes #6736

ajavadia opened this issue Jul 13, 2021 · 4 comments · Fixed by #6738
Labels
bug Something isn't working
Milestone

Comments

@ajavadia
Copy link
Member

Trying to get a subgraph of this coupling map:

from qiskit.test.mock import FakeMumbai
from retworkx.visualization import mpl_draw
backend = FakeMumbai()
cmap = CouplingMap(backend.configuration().coupling_map)
mpl_draw(cmap.graph)

image

If I use retworkx directly to get the subgraph on 9 nodes, it gives me this which is correct I think:

mpl_draw(cmap.graph.subgraph([0, 1, 4, 7, 10, 12, 15, 18, 17]))

image

But if I do the same using the CouplingMap API I get this. There are incorrect nodes added here:

cmap.subgraph([0, 1, 4, 7, 10, 12, 15, 18, 17]).draw()

image

@mtreinish says this is due to a difference in how networkx and retworkx implement .subgraph(). But I like the retworkx output because it numbers nodes as 0-k, and that is consistent with how coupling maps in qiskit are numbered (i.e. no "holes"). So I think something just needs to change here to remove the extra nodes. If we provide an option to keep the original node numberings, I'd be fine with that, but I'm not sure whether Qiskit can actually work with such a coupling map object. The best route I see is to remap the node numbers in the same order (smallest to 0, largest to k).

@ajavadia ajavadia added the bug Something isn't working label Jul 13, 2021
@mtreinish
Copy link
Member

mtreinish commented Jul 13, 2021

Right, so if we don't care about retaining node indices (and I agree that it breaks the assumptions of the CouplingMap class if we did retain the ids) then we can just remove https://github.com/Qiskit/qiskit-terra/blob/main/qiskit/transpiler/coupling.py#L118-L120 as retworkx does everything we need and this is fixed.

If for some reason (which I don't think there is any) we want to retain node ids (either by default or with a flag) we can do this, but the easiest way will require a retworkx PR to add an option for that (we can try to do it in python but it will require adding and removing nodes to create index holes as expected).

@ajavadia
Copy link
Member Author

Also I think the arg should be a set, not a list. Otherwise we have to renumber the ids based on the order passed, which could be a bit confusing I think. But I need to think about this a bit more.

@mtreinish
Copy link
Member

At least for the retwork implementation the order of the list isn't preserved. The first thing it does is convert it to a HashSet internally and then uses that to create an internal iterator for a subset of the graph that is looped over to create a copy:

https://github.com/Qiskit/retworkx/blob/main/src/digraph.rs#L2389-L2417

I think that will preserve index sorted order, but I wouldn't count on that as a guarantee either more just a side effect.

mtreinish added a commit to mtreinish/qiskit-core that referenced this issue Jul 13, 2021
This commit fixes the subgraph() method on the coupling map class when
the node list had a non-contiguous list that didn't start at 0.
Previously, the subgraph method would inject nodes for the holes in the
node list so that all the indices specified in the nodelist argument
were present in the output subgraph. But this was neglecting the nodes
get reindexed and wasn't valid. This commit fixes this by just removing
that step and relying on retworkx's subgraph() method to do the
underlying work.

Fixes Qiskit#6736
@itoko
Copy link
Contributor

itoko commented Jul 16, 2021

Reading this issue, I've noticed the difference between subgraph() and reduce(), two similar functions in CouplingMap. subgraph() does not care about the order of passed qubits while reduce() does.

coupling = CouplingMap.from_line(6, bidirectional=False)
list(coupling.subgraph([4, 2, 3, 5]).get_edges())
>>> [(0, 1), (1, 2), (2, 3)]
list(coupling.reduce([4, 2, 3, 5]).get_edges())
>>> [(1, 2), (2, 0), (0, 3)]

(I'm using reduce() in #6756)

Another issue, but we could consolidate these two functions into one adding optional args like validate_connection and retain_ordering in the future. (To me, subgraph sounds like retaining node labels and reduce sounds good)

@mergify mergify bot closed this as completed in #6738 Jul 27, 2021
mergify bot added a commit that referenced this issue Jul 27, 2021
This commit fixes the subgraph() method on the coupling map class when
the node list had a non-contiguous list that didn't start at 0.
Previously, the subgraph method would inject nodes for the holes in the
node list so that all the indices specified in the nodelist argument
were present in the output subgraph. But this was neglecting the nodes
get reindexed and wasn't valid. This commit fixes this by just removing
that step and relying on retworkx's subgraph() method to do the
underlying work.

Fixes #6736

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Kevin Krsulich <kevin.krsulich@ibm.com>
mergify bot pushed a commit that referenced this issue Jul 27, 2021
This commit fixes the subgraph() method on the coupling map class when
the node list had a non-contiguous list that didn't start at 0.
Previously, the subgraph method would inject nodes for the holes in the
node list so that all the indices specified in the nodelist argument
were present in the output subgraph. But this was neglecting the nodes
get reindexed and wasn't valid. This commit fixes this by just removing
that step and relying on retworkx's subgraph() method to do the
underlying work.

Fixes #6736

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Kevin Krsulich <kevin.krsulich@ibm.com>
(cherry picked from commit 0c6890d)
mergify bot added a commit that referenced this issue Jul 27, 2021
)

This commit fixes the subgraph() method on the coupling map class when
the node list had a non-contiguous list that didn't start at 0.
Previously, the subgraph method would inject nodes for the holes in the
node list so that all the indices specified in the nodelist argument
were present in the output subgraph. But this was neglecting the nodes
get reindexed and wasn't valid. This commit fixes this by just removing
that step and relying on retworkx's subgraph() method to do the
underlying work.

Fixes #6736

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Kevin Krsulich <kevin.krsulich@ibm.com>
(cherry picked from commit 0c6890d)

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
@kdk kdk added this to the 0.19 milestone Nov 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants