Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve codecov results #9

Merged
merged 3 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ ignore:
- "**/python"
- "test/**/*"
- "src/mqt/debug/dap/**/*"
- "src/mqt/debug/dap/*"
- "app/*"
- "src/frontend/**/*"

coverage:
range: 60..90
Expand Down
12 changes: 0 additions & 12 deletions include/common/parsing/AssertionParsing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
enum class AssertionType : uint8_t {
Entanglement,
Superposition,
Span,
StatevectorEquality,
CircuitEquality
};
Expand All @@ -36,17 +35,6 @@ class SuperpositionAssertion : public Assertion {
explicit SuperpositionAssertion(std::vector<std::string> targetQubits);
};

class SpanAssertion : public Assertion {
std::vector<Statevector> spanVectors;

public:
SpanAssertion(std::vector<Statevector> spanVectors,
std::vector<std::string> targetQubits);
[[nodiscard]] const std::vector<Statevector>& getSpanVectors() const;

~SpanAssertion() override;
};

class EqualityAssertion : public Assertion {
double similarityThreshold;

Expand Down
11 changes: 0 additions & 11 deletions src/backend/dd/DDSimDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,12 +955,6 @@ bool checkAssertionSuperposition(
return found > 1;
}

[[noreturn]] bool
checkAssertionSpan([[maybe_unused]] DDSimulationState* ddsim,
[[maybe_unused]] std::unique_ptr<SpanAssertion>& assertion) {
throw std::runtime_error("Span assertions are not implemented");
}

bool checkAssertionEqualityStatevector(
DDSimulationState* ddsim,
std::unique_ptr<StatevectorEqualityAssertion>& assertion) {
Expand Down Expand Up @@ -1044,11 +1038,6 @@ bool checkAssertion(DDSimulationState* ddsim,
assertion = std::move(superpositionAssertion);
return result;
}
if (assertion->getType() == AssertionType::Span) {
std::unique_ptr<SpanAssertion> spanAssertion(
dynamic_cast<SpanAssertion*>(assertion.release()));
checkAssertionSpan(ddsim, spanAssertion);
}
if (assertion->getType() == AssertionType::StatevectorEquality) {
std::unique_ptr<StatevectorEqualityAssertion> svEqualityAssertion(
dynamic_cast<StatevectorEqualityAssertion*>(assertion.release()));
Expand Down
47 changes: 5 additions & 42 deletions src/common/parsing/AssertionParsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "common/parsing/ParsingError.hpp"
#include "common/parsing/Utils.hpp"

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <memory>
Expand All @@ -30,27 +31,6 @@ SuperpositionAssertion::SuperpositionAssertion(
std::vector<std::string> inputTargetQubits)
: Assertion(std::move(inputTargetQubits), AssertionType::Superposition) {}

SpanAssertion::SpanAssertion(std::vector<Statevector> inputSpanVectors,
std::vector<std::string> inputTargetQubits)
: Assertion(std::move(inputTargetQubits), AssertionType::Span),
spanVectors(std::move(inputSpanVectors)) {
for (auto& statevector : spanVectors) {
if (statevector.numQubits != getTargetQubits().size()) {
throw ParsingError(
"Number of target qubits must match number of qubits in statevector");
}
}
}
const std::vector<Statevector>& SpanAssertion::getSpanVectors() const {
return spanVectors;
}
SpanAssertion::~SpanAssertion() {
for (auto& statevector : spanVectors) {
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
delete[] statevector.amplitudes;
}
}

EqualityAssertion::EqualityAssertion(double inputSimilarityThreshold,
std::vector<std::string> inputTargetQubits,
AssertionType assertionType)
Expand Down Expand Up @@ -93,7 +73,10 @@ const std::string& CircuitEqualityAssertion::getCircuitCode() const {
}

std::vector<std::string> extractTargetQubits(const std::string& targetPart) {
return splitString(targetPart, ',');
const auto parts = splitString(targetPart, ',');
std::vector<std::string> trimmedParts(parts.size());
std::transform(parts.begin(), parts.end(), trimmedParts.begin(), trim);
return trimmedParts;
}

Complex parseComplex(std::string complexString) {
Expand Down Expand Up @@ -143,7 +126,6 @@ bool isAssertion(std::string expression) {
expression = trim(expression);
return startsWith(expression, "assert-ent") ||
startsWith(expression, "assert-sup") ||
startsWith(expression, "assert-span") ||
startsWith(expression, "assert-eq");
}

Expand All @@ -159,25 +141,6 @@ std::unique_ptr<Assertion> parseAssertion(std::string assertionString,
auto targets = extractTargetQubits(assertionString.substr(11));
return std::make_unique<SuperpositionAssertion>(targets);
}
if (startsWith(assertionString, "assert-span")) {
auto sub = assertionString.substr(12);
auto targets = extractTargetQubits(sub);
auto statevectors = splitString(blockContent, ';');
std::vector<Statevector> statevectorList(statevectors.size());
for (auto& statevector : statevectors) {
statevectorList.emplace_back(parseStatevector(statevector));
}

auto assertion = std::make_unique<SpanAssertion>(statevectorList, targets);
auto svSize = statevectorList[0].numStates;
for (auto& sv : statevectorList) {
if (sv.numStates != svSize) {
throw ParsingError(
"Statevectors in span assertion must have the same size");
}
}
return assertion;
}
if (startsWith(assertionString, "assert-eq")) {
auto sub = assertionString.substr(10);
auto targets = extractTargetQubits(sub);
Expand Down
3 changes: 2 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ package_add_test(
test_simulation.cpp
test_data_retrieval.cpp
test_diagnostics.cpp
test_custom_code.cpp)
test_custom_code.cpp
test_parsing.cpp)

# set include directories
target_include_directories(mqt_debug_test PUBLIC ${PROJECT_SOURCE_DIR}/test/utils)
11 changes: 11 additions & 0 deletions test/test_custom_code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,14 @@ TEST_F(CustomCodeTest, GateInGateName) {
"assert-eq q[0] { 0, 1 }");
state->runSimulation(state);
}

TEST_F(CustomCodeTest, EqualityAssertion) {
loadCode(2, 0,
"h q[0];"
"cx q[0], q[1];"
"assert-eq 0.9, q[0], q[1] { 0.707, 0, 0, 0.707 }"
"assert-eq q[0], q[1] { qreg q[2]; h q[1]; cx q[1], q[0]; }");
size_t numErrors = 0;
ASSERT_EQ(state->runAll(state, &numErrors), OK);
ASSERT_EQ(numErrors, 0);
}
64 changes: 64 additions & 0 deletions test/test_parsing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "common/parsing/AssertionParsing.hpp"
#include "common/parsing/ParsingError.hpp"

#include <gtest/gtest.h>
#include <memory>
#include <string>

class ParsingTest : public testing::Test {
void SetUp() override {}
};

TEST_F(ParsingTest, EqualityAssertion) {
// With statevector
const auto a1 = parseAssertion("assert-eq 0.5, q[0]", "1, 0");
ASSERT_EQ(a1->getType(), AssertionType::StatevectorEquality);
ASSERT_EQ(a1->getTargetQubits().size(), 1);
ASSERT_EQ(a1->getTargetQubits()[0], "q[0]");
const auto* sv = dynamic_cast<StatevectorEqualityAssertion*>(a1.get());
ASSERT_EQ(sv->getSimilarityThreshold(), 0.5);
ASSERT_EQ(sv->getTargetStatevector().numQubits, 1);
ASSERT_EQ(sv->getTargetStatevector().numStates, 2);
ASSERT_EQ(sv->getTargetStatevector().amplitudes->real, 1);

// With circuit
const auto a2 = parseAssertion("assert-eq 0.5, q[0]", "qreg q[1]; h q[0];");
ASSERT_EQ(a2->getType(), AssertionType::CircuitEquality);
ASSERT_EQ(a2->getTargetQubits().size(), 1);
ASSERT_EQ(a2->getTargetQubits()[0], "q[0]");
const auto* c = dynamic_cast<CircuitEqualityAssertion*>(a2.get());
ASSERT_EQ(c->getSimilarityThreshold(), 0.5);
ASSERT_EQ(c->getCircuitCode(), "qreg q[1]; h q[0];");
}

TEST_F(ParsingTest, EntanglementAssertion) {
const auto a = parseAssertion("assert-ent q[0], q[1]", "");
ASSERT_EQ(a->getType(), AssertionType::Entanglement);
ASSERT_EQ(a->getTargetQubits().size(), 2);
ASSERT_EQ(a->getTargetQubits()[0], "q[0]");
ASSERT_EQ(a->getTargetQubits()[1], "q[1]");
}

TEST_F(ParsingTest, SuperpositionAssertion) {
const auto a = parseAssertion("assert-sup q[0], q[1]", "");
ASSERT_EQ(a->getType(), AssertionType::Superposition);
ASSERT_EQ(a->getTargetQubits().size(), 2);
ASSERT_EQ(a->getTargetQubits()[0], "q[0]");
ASSERT_EQ(a->getTargetQubits()[1], "q[1]");
}

TEST_F(ParsingTest, ErrorStatevectorEqualityAssertion) {
ASSERT_THROW(parseAssertion("assert-eq 1.5, q[0]", "1, 0"), ParsingError);
ASSERT_THROW(parseAssertion("assert-eq 0.5, q[0]", "1, 0, 0"), ParsingError);
ASSERT_THROW(parseAssertion("assert-eq 0.5, q[0]", "1, 0, 0, 0"),
ParsingError);
}

TEST_F(ParsingTest, ErrorCircuitEqualityAssertion) {
ASSERT_THROW(parseAssertion("assert-eq 1.5, q[0]", "qreg q[1]; h q[0];"),
ParsingError);
}

TEST_F(ParsingTest, ErrorInvalidAssertion) {
ASSERT_THROW(parseAssertion("assert-fake q[0]", ""), ParsingError);
}
Loading