-
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
Leverage rustworkx node and edge count hints in transpiler #12812
Conversation
This commit updates the DAGCircuit construction in the transpiler to use the newly introduced node_count_hint and edge_count_hint kwargs on the rustworkx graph constructors. In situations where we know the size of the dag or at least the lower bound we can reduce the number of underlying memory allocations by preallocating that size when we create the inner graph object. This commit adds private arguments to the DAGCircuit constructor which are used to provide these size hints to rustworkx.
One or more of the following people are relevant to this code:
|
Pull Request Test Coverage Report for Build 10150963487Details
💛 - Coveralls |
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.
The use of count hints looks straightforward to me. I would have to look into the passes better to fully get where some of the counts are coming from, but I guess that there isn't any big issue if the tests pass.
_node_count_hint=3 * num_qubits, | ||
_edge_count_hint=2 * num_qubits, |
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.
Usual question for me, how did you reach a node count (hint) of 3*num_qubits
here?
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.
85028d5
to
5da0be5
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.
In general this seems like a good idea. There's a few places where the amount of calculation / private-method accessing we're doing is sufficiently high that it might not be worthwhile in Python space, but I don't feel strongly.
The hints in copy_empty_like
feel a bit more awkward - they make sense in in the context of copy
or if the DAG will be refilled, but for things like layers
, the overallocation feels like it could get quite out-of-hand.
target_dag = DAGCircuit( | ||
node_count_hint=self._multi_graph.num_nodes(), | ||
edge_count_hint=self._multi_graph.num_edges(), | ||
) | ||
target_dag.name = self.name | ||
target_dag._global_phase = self._global_phase | ||
target_dag.duration = self.duration |
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.
Should copy_empty_like
eagerly allocate to the full size? Feels like that could be overallocating a bit. Maybe we want to control it with a single flag?
num_nodes = 2 * (len(physical_qubits) + dag.num_clbits() + dag.num_vars) | ||
num_edges = 0 | ||
for component in components: | ||
component_dag = component.dag | ||
size = len(component_dag._multi_graph) - 2 * len(component_dag._wires) | ||
num_nodes += size | ||
num_edges += component_dag._multi_graph.num_edges() | ||
|
||
mapped_dag = DAGCircuit( | ||
node_count_hint=num_nodes, | ||
edge_count_hint=num_edges, | ||
) |
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 suspicious that the Python-space time to calculate this stuff is quite possibly similar to the Rust-space time to just grow the vectors.
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.
Yeah, I was worried about this too. In practice I think the list is only ever a single list entry here though. The code handles disjoint connectivity, but iirc it was unsound to do the routing split up so we bail return an unrouted circuit before this gets called if the number of components is >1.
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 fine to just leave it anyway - it's probably just going to be a wash at worst, rather than hurting.
I'm going to close this as it's no longer relevant since we've moved the |
Summary
This commit updates the DAGCircuit construction in the transpiler to use the newly introduced node_count_hint and edge_count_hint kwargs on the rustworkx graph constructors. In situations where we know the size of the dag or at least the lower bound we can reduce the number of underlying memory allocations by preallocating that size when we create the inner graph object. This commit adds private arguments to the DAGCircuit constructor which are used to provide these size hints to rustworkx.
Details and comments