-
Notifications
You must be signed in to change notification settings - Fork 61
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
Optimize shortestpath in SABRE #1408
Conversation
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
Previous approach
self._temporary_added_swaps: int
self._saved_circuit: CircuitMap qibo/src/qibo/transpiler/router.py Lines 900 to 901 in 9db9b66
qibo/src/qibo/transpiler/router.py Lines 689 to 693 in 9db9b66
Updated approach
self._temp_added_swaps: list qibo/src/qibo/transpiler/router.py Lines 817 to 818 in a7a1c62
qibo/src/qibo/transpiler/router.py Lines 701 to 708 in a7a1c62
Results
Before update: 0.558s Discussion
|
for more information, see https://pre-commit.ci
Thank you for this work, the code looks nice.
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #1408 +/- ##
=======================================
Coverage 99.94% 99.94%
=======================================
Files 78 78
Lines 11225 11237 +12
=======================================
+ Hits 11219 11231 +12
Misses 6 6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
@Simone-Bordoni , I have a question about the qibo/tests/test_transpiler_router.py Line 264 in a2f7424
The function includes the following code: ...
initial_layout = {"q0": 2, "q1": 0, "q2": 1, "q3": 3}
...
circuit_map.update((0, 2)) # first swap
...
circuit_map.update((1, 2)) # second swap
assert routed_circuit.queue[5].qubits == (2, 0) # routed_circuit.queue[5] is the second swap After the first swap, the layout should be converted to: {"q0": 0, "q1": 2, "q2": 1, "q3": 3} since After the second swap, the swap should be on logical qubits (1, 2). So, the layout will be changed to: {"q0": 0, "q1": 1, "q2": 2, "q3": 3} Does this mean that the qubits affected by the swap are q2 and q1? assert routed_circuit.queue[5].qubits == (2, 1) Since Thank you for your time. |
src/qibo/transpiler/router.py
Outdated
def undo(self, swap: tuple): | ||
"""Undo the last swap. | ||
|
||
If the last block is not a swap or does not match the swap to undo, an error is raised. | ||
Method works in-place. | ||
|
||
Args: | ||
swap (tuple): tuple containing the logical qubits to be swapped. | ||
""" | ||
physical_swap = self.logical_to_physical(swap, index=True) | ||
last_swap_block = self._routed_blocks.return_last_block() | ||
if last_swap_block.gates[0].__class__ != gates.SWAP or sorted( | ||
last_swap_block.qubits | ||
) != sorted(physical_swap): | ||
raise_error( | ||
ConnectivityError, | ||
"The last block does not match the swap to undo.", | ||
) | ||
self._routed_blocks.remove_block(last_swap_block) | ||
self._swaps -= 1 | ||
|
||
idx_0, idx_1 = self._circuit_logical.index( | ||
swap[0] | ||
), self._circuit_logical.index(swap[1]) | ||
self._circuit_logical[idx_0], self._circuit_logical[idx_1] = swap[1], swap[0] |
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 looks ok code-wise, the only thing that seems a bit weird to me is that the undo
requires for you to pass the swap
you wish to undo. I mean, since in principle you undo the last one, you wouldn't need to pass explicitely the swap, but just look for the last one added in a routed block, right? And, indeed, here swap
is only used to check that the last swap you find is the one you expected.
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 used swap
to double-check if the undo function works correctly. I'll remove the checking step.
Also, could you take a look at the question I posted above?
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.
Sorry for the delay. Double checking could always be useful, indeed, but, if you want to keep it, I wouldn't make it mandatory at least. In the sense that you could have the swap=None
argument as optional. In any case, this check should be covered in the tests in principle.
Regarding the question above, instead, I had a look at it last week. Now, the best person to answer this is probably @Simone-Bordoni, but I believe he is currently on a leave. Thus, I will provide you with my guess, which however may be incorrect. By looking at the update
function
qibo/src/qibo/transpiler/router.py
Line 241 in a2f7424
def update(self, swap: tuple): |
it seems that you update the
circuit_logical
mapping, not the physical one (physical_logical
), meaning that in the layout dict, you do not swap the values, but rather the keys.Therefore you start from:
{"q0": 0, "q1": 2, "q2": 1, "q3": 3}
after the (0, 2)
swap you get:
{"q2": 0, "q1": 2, "q0": 1, "q3": 3}
and after (1, 2)
:
{"q1": 0, "q2": 2, "q0": 1, "q3": 3}
This means that you end up with circuit_logical = [1, 2, 0, 3]
, which is indeed checked in the test:
assert circuit_map._circuit_logical == [1, 2, 0, 3]
I hope this helped, assuming it is correct. In general, though, this small review of the transpiler code that I did to find the answer, made me think that probably, both, the naming scheme could be improved to make it clearer, and some further documentation should be added to the docstrings. Otherwise, everytime we go back to the code, we risk to waste time in re-understanding everything.
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 your response. I noticed that while optimizing SABRE and a better naming scheme seems to be needed. I also found and implemented a more efficient way to manage the mapping. I think it would be best to wait until @Simone-Bordoni returns to discuss the new mapping scheme.
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 am currently on leaves. If you want to implement a new mapping scheme you can do the PR and I will review it when I will be back.
This PR is an addition to #1398.
Since
deepcopy()
makes the compiler slower, it needs to be changed.code
Line 901 takes over 30% of the routing time.
Checklist: