Closed nquetschlich closed 1 month ago
Hi, Thanks a lot for rasing this. One of us will take a look.
Hi,
FullPeepholeOptimise
is not connectivity preserving even with allow_swaps
set to false
. This is because it uses a three-qubit synthesis that can introduce non-local gates, which may break connectivity constraints. You may want to experiment with other passes for post-routing optimisation, such as CliffordSimp(allow_swaps =False)
and KAKDecomposition(allow_swaps=False)
.
I think it should be made a bit clearer to the user what the allow_swaps=False
flag means. In the case of FullPeepholeOptimise
does allow_swaps=False
just prevent implicit swaps?
We do have FullPeepholeOptimise2Q which omits the three qubit squashing so this should preserve connectivity.
I think it should be made a bit clearer to the user what the
allow_swaps=False
flag means. In the case ofFullPeepholeOptimise
doesallow_swaps=False
just prevent implicit swaps?That's right,
allow_swaps=False
just prevent implicit swaps.
I think it should be made a bit clearer to the user what the
allow_swaps=False
flag means. In the case ofFullPeepholeOptimise
doesallow_swaps=False
just prevent implicit swaps?We do have FullPeepholeOptimise2Q which omits the three qubit squashing so this should preserve connectivity.
Thank you very much for pointing me to that optimization pass. I tried it out but it seems that even PeepholeOptimise2Q
does not preserve the connectivity. In the attached code snippet, the pass leads to an invalid connectivity. If it is commented out, the connectivity is valid.
from pytket import architecture, OpType
from qiskit.providers.fake_provider import FakeMontreal
from pytket.passes import (
auto_rebase_pass,
CXMappingPass,
PeepholeOptimise2Q
)
from pytket.placement import LinePlacement
from pytket.qasm import circuit_from_qasm_str
cmap = FakeMontreal().configuration().coupling_map
arch = architecture.Architecture(cmap)
native_gate_set_rebase = auto_rebase_pass({OpType.Rz, OpType.SX, OpType.X, OpType.CX, OpType.Measure})
qc_tket = circuit_from_qasm_str('OPENQASM 2.0;\ninclude "qelib1.inc";\n\nqreg q[11];\ncreg meas[11];\nry(0.5156200785337115*pi) q[0];\nry(0.5259212361027874*pi) q[1];\nry(0.5311490773594357*pi) q[2];\nry(0.5256341606456719*pi) q[3];\nry(0.48185482198855123*pi) q[4];\nry(0.3749999999999992*pi) q[5];\nx q[6];\nx q[7];\nx q[8];\ncx q[4],q[3];\nry(0.2821957516304727*pi) q[3];\ncx q[4],q[3];\ncx q[3],q[2];\nry(0.08637935492365122*pi) q[2];\ncx q[4],q[2];\nry(0.03914176090442699*pi) q[2];\ncx q[3],q[2];\nry(0.17701662922799363*pi) q[2];\ncx q[4],q[2];\ncx q[2],q[1];\nry(0.02736736175234687*pi) q[1];\ncx q[3],q[1];\nry(0.006775452169044077*pi) q[1];\ncx q[2],q[1];\nry(0.05465580935192185*pi) q[1];\ncx q[4],q[1];\nry(0.028714621193555362*pi) q[1];\ncx q[2],q[1];\nry(0.00293352636765904*pi) q[1];\ncx q[3],q[1];\nry(0.014080566388901176*pi) q[1];\ncx q[2],q[1];\nry(0.10244302344157596*pi) q[1];\ncx q[4],q[1];\ncx q[1],q[0];\nry(0.007775077506101111*pi) q[0];\ncx q[2],q[0];\nry(0.001240726382892508*pi) q[0];\ncx q[1],q[0];\nry(0.015455307725784545*pi) q[0];\ncx q[3],q[0];\nry(0.004852553186980698*pi) q[0];\ncx q[1],q[0];\nry(0.000403832853185929*pi) q[0];\ncx q[2],q[0];\nry(0.002436170270185542*pi) q[0];\ncx q[1],q[0];\nry(0.030093570893275967*pi) q[0];\ncx q[4],q[0];\nry(0.016793599745076833*pi) q[0];\ncx q[1],q[0];\nry(0.0014820670980056393*pi) q[0];\ncx q[2],q[0];\nry(0.00024834944107055316*pi) q[0];\ncx q[1],q[0];\nry(0.002959396507430131*pi) q[0];\ncx q[3],q[0];\nry(0.008651443455406324*pi) q[0];\ncx q[1],q[0];\nry(0.0007488027442816633*pi) q[0];\ncx q[2],q[0];\nry(0.0043527049236130886*pi) q[0];\ncx q[1],q[0];\nry(0.05440168109764556*pi) q[0];\ncx q[4],q[0];\ncry(0.0*pi) q[0],q[5];\ncry(0.0*pi) q[1],q[5];\nx q[1];\ncry(0.0*pi) q[2],q[5];\nccx q[1],q[7],q[8];\ncry(0.0*pi) q[3],q[5];\nx q[1];\nccx q[2],q[8],q[9];\ncry(0.0*pi) q[4],q[5];\nx q[7];\nx q[1];\nccx q[3],q[9],q[10];\nx q[4];\nu1(0.0*pi) q[5];\nx q[7];\nx q[10];\nccx q[4],q[10],q[6];\nx q[4];\nu1(0.0*pi) q[6];\nx q[10];\nccx q[3],q[9],q[10];\ncx q[6],q[5];\nccx q[2],q[8],q[9];\nu3(0.09366343673910417*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nx q[8];\nccx q[1],q[7],q[8];\nu3(3.9063365632608957*pi,0.0*pi,0.0*pi) q[5];\nu1(0.0*pi) q[6];\nx q[1];\nu1(0.0*pi) q[5];\nx q[7];\ncx q[6],q[5];\nx q[7];\nu3(3.9964731703751757*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nu3(0.0035268296248242787*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[0],q[5];\nu1(0.0*pi) q[5];\nu1(0.0*pi) q[6];\ncx q[6],q[5];\nu3(0.0035268296248242787*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nu3(3.9964731703751757*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[0],q[5];\nu1(0.0*pi) q[5];\nu1(0.0*pi) q[6];\ncx q[6],q[5];\nu3(3.9929463407503514*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nu3(0.007053659249648525*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[1],q[5];\nu1(0.0*pi) q[5];\nu1(0.0*pi) q[6];\ncx q[6],q[5];\nu3(0.007053659249648525*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nu3(3.9929463407503514*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[1],q[5];\nx q[1];\nu1(0.0*pi) q[5];\nu1(0.0*pi) q[6];\nccx q[1],q[7],q[8];\ncx q[6],q[5];\nx q[1];\nu3(3.9858926815007027*pi,0.0*pi,0.0*pi) q[5];\nx q[7];\nx q[8];\nx q[1];\ncx q[6],q[5];\nx q[7];\nu3(0.01410731849929705*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[2],q[5];\nu1(0.0*pi) q[5];\nu1(0.0*pi) q[6];\ncx q[6],q[5];\nu3(0.01410731849929705*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nu3(3.9858926815007027*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[2],q[5];\nccx q[2],q[8],q[9];\nu1(0.0*pi) q[5];\nu1(0.0*pi) q[6];\ncx q[6],q[5];\nu3(3.971785363001406*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nu3(0.0282146369985941*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[3],q[5];\nu1(0.0*pi) q[5];\nu1(0.0*pi) q[6];\ncx q[6],q[5];\nu3(0.0282146369985941*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nu3(3.971785363001406*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[3],q[5];\nccx q[3],q[9],q[10];\nu1(0.0*pi) q[5];\nu1(0.0*pi) q[6];\ncx q[6],q[5];\nx q[10];\nu3(3.943570726002812*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nu3(0.0564292739971882*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[4],q[5];\nu1(0.0*pi) q[5];\nu1(0.0*pi) q[6];\ncx q[6],q[5];\nu3(0.0564292739971882*pi,0.0*pi,0.0*pi) q[5];\ncx q[6],q[5];\nu3(3.943570726002812*pi,0.0*pi,0.0*pi) q[5];\nccx q[6],q[4],q[5];\nx q[4];\nccx q[4],q[10],q[6];\nx q[4];\nx q[6];\nx q[10];\nccx q[3],q[9],q[10];\nccx q[2],q[8],q[9];\nccx q[1],q[7],q[8];\nx q[1];\nx q[7];\nx q[8];\nbarrier q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7],q[8],q[9],q[10];\nmeasure q[0] -> meas[0];\nmeasure q[1] -> meas[1];\nmeasure q[2] -> meas[2];\nmeasure q[3] -> meas[3];\nmeasure q[4] -> meas[4];\nmeasure q[5] -> meas[5];\nmeasure q[6] -> meas[6];\nmeasure q[7] -> meas[7];\nmeasure q[8] -> meas[8];\nmeasure q[9] -> meas[9];\nmeasure q[10] -> meas[10];\n')
diff = 27 - qc_tket.n_qubits
qc_tket.add_blank_wires(diff)
native_gate_set_rebase.apply(qc_tket)
CXMappingPass(arc=arch, placer=LinePlacement(arch), directed_cx=True, delay_measures=False).apply(qc_tket)
PeepholeOptimise2Q().apply(qc_tket)
native_gate_set_rebase.apply(qc_tket)
print(qc_tket.valid_connectivity(arch, directed=True))
Am I using the PeepholeOptimise2Q
not as intended?
Hey @nquetschlich, sorry for the confusion. I found the issue - turns out that PeepholeOptimise2Q
isn't preserving connectivity because the allow_swaps
flag for its underlying KAKDecomposition
and KAKDecomposition
passes are set to True
.
To fix this, we can add an allow_swaps
argument to PeepholeOptimise2Q
and setting it to False
preserves connectivity. But in the meantime, you can do the same thing by following these steps:
SynthesiseTket().apply(qc_tket)
KAKDecomposition(allow_swaps=False).apply(qc_tket)
CliffordSimp(allow_swaps=False).apply(qc_tket)
SynthesiseTket().apply(qc_tket)
Hi @yao-cqc, thank you very much for finding out. I will use the work-around you suggested and change as soon as the updated PeepholeOptimise2Q
pass is released.
Hi,
Now that pytket 1.16 is released you should be able to use the allow_swaps=False
flag in FullPeepholeOptimise2Q
This issue has been automatically marked as stale.
Hi,
I think I may found a case (using pytket v1.11.1) where the
FullPeepholeOptimise
compilation pass did not preserve the connectivity althoughallow_swaps=False
is set.Here is the code leading to
valid_connectivity(...)
returningFalse
:In this case, three invalid operations were inserted:
If the
FullPeepholeOptimise
pass is not used, everything works as expected.