Skip to content

Commit b159b2e

Browse files
authored
🐛 Fix cost contribution of direction reverse in exact mapper (#252)
## Description Fixes #251. For some reason the cost contribution of direction reverses in the exact mapper was inverted, i.e., the mapper effectively considered direction reverses to be "free". This PR fixes the underlying condition and adds a corresponding regression test. ## Checklist: <!--- This checklist serves as a reminder of a couple of things that ensure your pull request will be merged swiftly. --> - [x] The pull request only contains commits that are related to it. - [x] I have added appropriate tests and documentation. - [x] I have made sure that all CI jobs on GitHub pass. - [x] The pull request introduces no new warnings and follows the project's style guidelines.
2 parents f249df6 + 225e395 commit b159b2e

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

src/exact/ExactMapper.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -724,22 +724,23 @@ number of variables: (|L|-1) * m!
724724

725725
// cost for reversed directions
726726
if (!architecture.bidirectional()) {
727-
cost = LogicTerm(0);
728-
for (std::size_t k = 0; k < reducedLayerIndices.size(); ++k) {
727+
cost = LogicTerm(0);
728+
const auto numLayers = reducedLayerIndices.size();
729+
for (std::size_t k = 0; k < numLayers; ++k) {
729730
for (const auto& gate : layers.at(reducedLayerIndices.at(k))) {
730731
if (gate.singleQubit()) {
731732
continue;
732733
}
733734

734-
auto reverse = LogicTerm(true);
735-
for (const auto& edge : rcm) {
736-
auto indexFT = x[k][physicalQubitIndex[edge.first]][gate.target];
737-
auto indexSC = x[k][physicalQubitIndex[edge.second]]
738-
[static_cast<std::size_t>(gate.control)];
739-
reverse = reverse && (!indexFT || !indexSC);
735+
auto reverse = LogicTerm(false);
736+
for (const auto& [q0, q1] : rcm) {
737+
const auto indexFT = x[k][physicalQubitIndex[q0]][gate.target];
738+
const auto indexSC = x[k][physicalQubitIndex[q1]]
739+
[static_cast<std::size_t>(gate.control)];
740+
reverse = reverse || (indexFT && indexSC);
740741
}
741742
cost = cost + LogicTerm::ite(reverse,
742-
LogicTerm(GATES_OF_DIRECTION_REVERSE),
743+
LogicTerm(::GATES_OF_DIRECTION_REVERSE),
743744
LogicTerm(0));
744745
}
745746
}

test/test_exact.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#include "exact/ExactMapper.hpp"
77

8-
#include "gmock/gmock.h"
98
#include "gtest/gtest.h"
109

1110
class ExactTest : public testing::TestWithParam<std::string> {
@@ -534,3 +533,26 @@ TEST_F(ExactTest, Test4QCircuitThatUsesAll5Q) {
534533
const auto& results = mapper.getResults();
535534
EXPECT_EQ(results.output.swaps, 1);
536535
}
536+
537+
TEST_F(ExactTest, Test) {
538+
// Regression test for https://github.com/cda-tum/qmap/issues/251
539+
using namespace qc::literals;
540+
541+
Architecture arch;
542+
const CouplingMap cm = {{1, 0}, {2, 0}, {2, 1}, {4, 2}, {3, 2}, {3, 4}};
543+
arch.loadCouplingMap(5, cm);
544+
545+
Architecture::printCouplingMap(cm, std::cout);
546+
547+
qc = qc::QuantumComputation(4);
548+
qc.x(0, 1_pc);
549+
qc.x(1, 0_pc);
550+
qc.x(1, 2_pc);
551+
qc.x(2, 1_pc);
552+
qc.x(2, 3_pc);
553+
554+
auto mapper = ExactMapper(qc, arch);
555+
mapper.map(settings);
556+
EXPECT_EQ(mapper.getResults().output.swaps, 0);
557+
EXPECT_EQ(mapper.getResults().output.directionReverse, 2);
558+
}

0 commit comments

Comments
 (0)