Skip to content

Commit

Permalink
🐛 Fix cost contribution of direction reverse in exact mapper (#252)
Browse files Browse the repository at this point in the history
## 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.
  • Loading branch information
burgholzer authored Mar 1, 2023
2 parents f249df6 + 225e395 commit b159b2e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 10 deletions.
19 changes: 10 additions & 9 deletions src/exact/ExactMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,22 +724,23 @@ number of variables: (|L|-1) * m!

// cost for reversed directions
if (!architecture.bidirectional()) {
cost = LogicTerm(0);
for (std::size_t k = 0; k < reducedLayerIndices.size(); ++k) {
cost = LogicTerm(0);
const auto numLayers = reducedLayerIndices.size();
for (std::size_t k = 0; k < numLayers; ++k) {
for (const auto& gate : layers.at(reducedLayerIndices.at(k))) {
if (gate.singleQubit()) {
continue;
}

auto reverse = LogicTerm(true);
for (const auto& edge : rcm) {
auto indexFT = x[k][physicalQubitIndex[edge.first]][gate.target];
auto indexSC = x[k][physicalQubitIndex[edge.second]]
[static_cast<std::size_t>(gate.control)];
reverse = reverse && (!indexFT || !indexSC);
auto reverse = LogicTerm(false);
for (const auto& [q0, q1] : rcm) {
const auto indexFT = x[k][physicalQubitIndex[q0]][gate.target];
const auto indexSC = x[k][physicalQubitIndex[q1]]
[static_cast<std::size_t>(gate.control)];
reverse = reverse || (indexFT && indexSC);
}
cost = cost + LogicTerm::ite(reverse,
LogicTerm(GATES_OF_DIRECTION_REVERSE),
LogicTerm(::GATES_OF_DIRECTION_REVERSE),
LogicTerm(0));
}
}
Expand Down
24 changes: 23 additions & 1 deletion test/test_exact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

#include "exact/ExactMapper.hpp"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

class ExactTest : public testing::TestWithParam<std::string> {
Expand Down Expand Up @@ -534,3 +533,26 @@ TEST_F(ExactTest, Test4QCircuitThatUsesAll5Q) {
const auto& results = mapper.getResults();
EXPECT_EQ(results.output.swaps, 1);
}

TEST_F(ExactTest, Test) {
// Regression test for https://github.com/cda-tum/qmap/issues/251
using namespace qc::literals;

Architecture arch;
const CouplingMap cm = {{1, 0}, {2, 0}, {2, 1}, {4, 2}, {3, 2}, {3, 4}};
arch.loadCouplingMap(5, cm);

Architecture::printCouplingMap(cm, std::cout);

qc = qc::QuantumComputation(4);
qc.x(0, 1_pc);
qc.x(1, 0_pc);
qc.x(1, 2_pc);
qc.x(2, 1_pc);
qc.x(2, 3_pc);

auto mapper = ExactMapper(qc, arch);
mapper.map(settings);
EXPECT_EQ(mapper.getResults().output.swaps, 0);
EXPECT_EQ(mapper.getResults().output.directionReverse, 2);
}

0 comments on commit b159b2e

Please sign in to comment.