Skip to content

Commit 7e00033

Browse files
committed
🐛 fix permutation inference in exact mapper
when considering more qubits than in the original circuit, permutations in the circuit extraction of the exact mapper were sometimes inferred incorrectly. Signed-off-by: Lukas Burgholzer <lukas.burgholzer@jku.at>
1 parent 018bd87 commit 7e00033

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

src/exact/ExactMapper.cpp

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -796,22 +796,51 @@ number of variables: (|L|-1) * m!
796796
assert(choiceResults.output.directionReverse == 0U);
797797
// swaps
798798
for (std::size_t k = 1; k < reducedLayerIndices.size(); ++k) {
799-
auto& i = x[k - 1];
800-
auto& j = x[k];
801-
802-
for (const auto qubit : qubitChoice) {
803-
for (std::size_t q = 0; q < qc.getNqubits(); ++q) {
804-
if (m->getBoolValue(i[physicalQubitIndex[qubit]][q], lb.get())) {
805-
// logical qubit q was mapped to physical qubit Q
806-
for (const auto otherQubit : qubitChoice) {
807-
// and has been assigned to physical qubit P going forward
808-
if (m->getBoolValue(j[physicalQubitIndex[otherQubit]][q],
809-
lb.get())) {
810-
pi[physicalQubitIndex[qubit]] = otherQubit;
799+
if (qubitChoice.size() == qc.getNqubits()) {
800+
// When as many qubits of the architecture are being considered
801+
// as in the circuit, the assignment of the logical to the physical
802+
// qubits is a bijection. Hence, we the assignment matrices X can be
803+
// used to directly infer the permutation of the qubits in each layer.
804+
auto& oldAssignment = x[k - 1];
805+
auto& newAssignment = x[k];
806+
for (const auto physicalQubit : qubitChoice) {
807+
for (std::size_t logicalQubit = 0; logicalQubit < qc.getNqubits();
808+
++logicalQubit) {
809+
if (const auto oldIndex = physicalQubitIndex[physicalQubit];
810+
m->getBoolValue(oldAssignment[oldIndex][logicalQubit],
811+
lb.get())) {
812+
for (const auto newPhysicalQubit : qubitChoice) {
813+
if (const auto newIndex = physicalQubitIndex[newPhysicalQubit];
814+
m->getBoolValue(newAssignment[newIndex][logicalQubit],
815+
lb.get())) {
816+
pi[oldIndex] = newPhysicalQubit;
817+
break;
818+
}
811819
}
820+
break;
812821
}
813822
}
814823
}
824+
} else {
825+
// When more qubits of the architecture are being considered than are in
826+
// the circuit, the assignment of the logical to the physical qubits
827+
// cannot be a bijection. Hence, the permutation variables y have to be
828+
// used to infer the permutation of the qubits in each layer. This is
829+
// mainly because the additional qubits movement cannot be inferred
830+
// from the assignment matrices X.
831+
piCount = 0;
832+
internalPiCount = 0;
833+
// sort the permutation of the qubits to start fresh
834+
std::sort(pi.begin(), pi.end());
835+
do {
836+
if (skippedPi.count(piCount) == 0 || !config.enableSwapLimits) {
837+
if (m->getBoolValue(y[k - 1][internalPiCount], lb.get())) {
838+
break;
839+
}
840+
++internalPiCount;
841+
}
842+
++piCount;
843+
} while (std::next_permutation(pi.begin(), pi.end()));
815844
}
816845

817846
architecture.minimumNumberOfSwaps(pi, swaps.at(k));

0 commit comments

Comments
 (0)