-
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
Migrate ApproximateTokenSwapper to only use retworkx and make networkx optional #5471
Conversation
This commit removes the networkx usage in the ApproximateTokenSwapper to use retworkx instead. Besides being speeding up the execution of the pass what's more important here is that this was the last networkx usage in qiskit-terra (with the exeception of a couple compatibility converters in qiskit.dagcircuit). So this commit also makes networkx an optional dependency and updates the 3 methods (which are outside the common usage scenarios) to use runtime imports and emit a more detailed import error if networkx isn't installed. Fixes: Qiskit#5470 Related to: Qiskit#5100
There is a single dagcircuit test that uses the to_networkx() method. So we need to install networkx in test environments.
Cool, I see you narrowed the allowed types on the graph to integers. I assume that is because only integers are supported by retworkx? |
Sort of, retworkx graphs allow any python object as a node's data payload/weight, but all nodes are integer indexed, and unlike networkx, retworkx functions that take a node don't use an associative lookup based on the data payload and must be passed an index. I changed it to just be int because I have it work with only index when calling retworkx. We could change it to use anything but then we'd have to maintain a mapping of node data to node index somewhere (for dagcircuit we store the index in the dagnode, so it doesn't have to be a dict). |
Co-authored-by: Lauren Capelluto <[email protected]>
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.
Cool! 🎉
I ran some quick benchmarks of the token swapper just now: The big improvement in creation time for retworkx is at 300 nodes, it's the default threshold for using the multiple threads: https://retworkx.readthedocs.io/en/stable/stubs/retworkx.graph_distance_matrix.html It might be worth tuning that a bit and setting it to a lower number. (both graphs are log-log) I generated the data with: import time
import retworkx as rx
import numpy as np
from qiskit.transpiler.passes.routing.algorithms import ApproximateTokenSwapper
np.random.seed(42)
create_time = {}
map_time = {}
for size in np.logspace(2, 3, dtype=int):
print(size)
graph = rx.undirected_gnm_random_graph(size, size ** 2 // 10, seed=42)
for i in graph.node_indexes():
try:
graph.remove_edge(i, i) # Remove self-loops.
except rx.NoEdgeBetweenNodes:
continue
# Make sure the graph is connected by adding C_n
graph.add_edges_from_no_data(
[(i, i + 1) for i in range(len(graph) - 1)])
start = time.time()
swapper = ApproximateTokenSwapper(graph)
stop = time.time()
create_time[size] = stop - start
# Generate a randomized permutation.
rand_perm = np.random.permutation(graph.nodes())
permutation = dict(zip(graph.nodes(), rand_perm))
mapping = dict(itertools.islice(permutation.items(), 0, size, 2))
start = time.time()
out = list(swapper.map(mapping, trials=40))
stop = time.time()
map_time[size] = stop - start |
Summary
This commit removes the networkx usage in the ApproximateTokenSwapper to
use retworkx instead. Besides being speeding up the execution of the
pass what's more important here is that this was the last networkx usage
in qiskit-terra (with the exeception of a couple compatibility
converters in qiskit.dagcircuit). So this commit also makes networkx an
optional dependency and updates the 3 methods (which are outside the
common usage scenarios) to use runtime imports and emit a more detailed
import error if networkx isn't installed.
Details and comments
Fixes: #5470
Related to: #5100