Skip to content

Commit

Permalink
🐛 Fix a div-by-zero in Proportional strategy for empty circuit (#317)
Browse files Browse the repository at this point in the history
## Description

This PR fixes a corner case where an empty circuit could lead to a
division by zero error when trying to compute the gate ration between
both circuits.
Furthermore, a shortcut is added for when both circuits are empty.

## 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 Oct 3, 2023
2 parents 7eb64b2 + c15ca99 commit 47ceb3b
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ class ProportionalApplicationScheme final
[[nodiscard]] std::size_t computeGateRatio() const noexcept {
const std::size_t size1 = this->taskManager1.getCircuit()->size();
const std::size_t size2 = this->taskManager2.getCircuit()->size();
if (size1 == 0U) {
return size2;
}
return std::max((size2 + (size1 / 2U)) / size1,
static_cast<std::size_t>(1U));
}

const std::size_t gateRatio;
std::size_t gateRatio;
};
} // namespace ec
6 changes: 6 additions & 0 deletions src/EquivalenceCheckingManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ void EquivalenceCheckingManager::run() {
return;
}

if (qc1.empty() && qc2.empty()) {
results.equivalence = EquivalenceCriterion::Equivalent;
done = true;
return;
}

if (qc1.isVariableFree() && qc2.isVariableFree()) {
if (!configuration.execution.parallel ||
configuration.execution.nthreads <= 1 ||
Expand Down
80 changes: 80 additions & 0 deletions test/test_equality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,83 @@ TEST_F(EqualityTest, ExceptionInParallelThread) {
ec::EquivalenceCheckingManager ecm(qc1, qc1, config);
EXPECT_THROW(ecm.run(), std::invalid_argument);
}

TEST_F(EqualityTest, BothCircuitsEmptyAlternatingChecker) {
config.execution.runAlternatingChecker = true;
ec::EquivalenceCheckingManager ecm(qc1, qc2, config);
ecm.setApplicationScheme(ec::ApplicationSchemeType::Proportional);
ecm.run();
EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent);
}

TEST_F(EqualityTest, BothCircuitsEmptyConstructionChecker) {
config.execution.runConstructionChecker = true;
ec::EquivalenceCheckingManager ecm(qc1, qc2, config);
ecm.setApplicationScheme(ec::ApplicationSchemeType::Proportional);
ecm.run();
EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent);
}

TEST_F(EqualityTest, BothCircuitsEmptySimulationChecker) {
config.execution.runSimulationChecker = true;
ec::EquivalenceCheckingManager ecm(qc1, qc2, config);
ecm.setApplicationScheme(ec::ApplicationSchemeType::Proportional);
ecm.run();
EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent);
}

TEST_F(EqualityTest, BothCircuitsEmptyZXChecker) {
config.execution.runZXChecker = true;
ec::EquivalenceCheckingManager ecm(qc1, qc2, config);
ecm.setApplicationScheme(ec::ApplicationSchemeType::Proportional);
ecm.run();
EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent);
}

TEST_F(EqualityTest, OneCircuitEmptyAlternatingChecker) {
qc2.h(0);
qc2.x(0);
qc2.h(0);
qc2.z(0);
config.execution.runAlternatingChecker = true;
ec::EquivalenceCheckingManager ecm(qc1, qc2, config);
ecm.setApplicationScheme(ec::ApplicationSchemeType::Proportional);
ecm.run();
EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent);
}

TEST_F(EqualityTest, OneCircuitEmptyConstructionChecker) {
qc2.h(0);
qc2.x(0);
qc2.h(0);
qc2.z(0);
config.execution.runConstructionChecker = true;
ec::EquivalenceCheckingManager ecm(qc1, qc2, config);
ecm.setApplicationScheme(ec::ApplicationSchemeType::Proportional);
ecm.run();
EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent);
}

TEST_F(EqualityTest, OneCircuitEmptySimulationChecker) {
qc2.h(0);
qc2.x(0);
qc2.h(0);
qc2.z(0);
config.execution.runSimulationChecker = true;
ec::EquivalenceCheckingManager ecm(qc1, qc2, config);
ecm.setApplicationScheme(ec::ApplicationSchemeType::Proportional);
ecm.run();
EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::ProbablyEquivalent);
}

TEST_F(EqualityTest, OneCircuitEmptyZXChecker) {
qc2.h(0);
qc2.x(0);
qc2.h(0);
qc2.z(0);
config.execution.runZXChecker = true;
ec::EquivalenceCheckingManager ecm(qc1, qc2, config);
ecm.setApplicationScheme(ec::ApplicationSchemeType::Proportional);
ecm.run();
EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent);
}

0 comments on commit 47ceb3b

Please sign in to comment.