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

Delayed Phase Correction #397

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c81eb40
Removed fixed gateset and replaced with parameter.
pehamTom Nov 10, 2023
5eb3747
Check if gateset is Clifford.
pehamTom Nov 10, 2023
8c9d539
Added completens check for single-qubit Gatesets.
pehamTom Nov 10, 2023
1cd55fd
Extracted Gateset in separate file and pass gateset through config.
pehamTom Nov 10, 2023
256f588
Bindings for Gateset.
pehamTom Nov 10, 2023
d218f42
Commit missing file.
pehamTom Nov 13, 2023
af8ee8f
Relax ExactlyOne constraint for depth-optimal synthesis.
pehamTom Nov 13, 2023
eb35989
Always add the none gate.
pehamTom Nov 13, 2023
b2e3a92
Merge branch 'tom-dev' into relax-exactly-one-constraint
pehamTom Nov 13, 2023
848e9d7
Removed templates.
pehamTom Nov 13, 2023
7690afa
Merge branch 'tom-dev' into relax-exactly-one-constraint
pehamTom Nov 13, 2023
d334f58
Made GateSet into an actual set.
pehamTom Nov 13, 2023
267c2b1
Merge branch 'tom-dev' into relax-exactly-one-constraint
pehamTom Nov 13, 2023
f58a738
Can only relax constraints if no Paulis are in the target Gateset.
pehamTom Nov 13, 2023
3b3f028
added setting for delaying paulis.
pehamTom Nov 13, 2023
e6c3348
Extract common functionality of different encoders.
pehamTom Nov 13, 2023
f45ac80
Added new class for handling the encoding for phase correction.
pehamTom Nov 14, 2023
cad2a04
Added files for encoder.
pehamTom Nov 14, 2023
c02c8ed
Encoding and tests for delayed phase correction.
pehamTom Nov 14, 2023
0608ae9
Fixed tests.
pehamTom Nov 14, 2023
e8d4794
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 14, 2023
b8423cc
Fix constexpr error.
pehamTom Nov 14, 2023
995ed9d
Merge remote-tracking branch 'origin/postpone-paulis' into postpone-p…
pehamTom Nov 14, 2023
6a3bafa
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 14, 2023
dac77bb
missing header?
pehamTom Nov 15, 2023
60f64ca
Merge remote-tracking branch 'origin/postpone-paulis' into postpone-p…
pehamTom Nov 15, 2023
4291548
Missing include.
pehamTom Nov 15, 2023
245f55c
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 15, 2023
a0652f0
Linter warnings.
pehamTom Nov 15, 2023
aaeb22f
Merge remote-tracking branch 'origin/postpone-paulis' into postpone-p…
pehamTom Nov 15, 2023
4b48b48
Fixed relation of consistency constraints.
pehamTom Nov 17, 2023
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
Prev Previous commit
Next Next commit
Added new class for handling the encoding for phase correction.
pehamTom committed Nov 14, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit f45ac80fa875aef72539f84f5d4fe6d98cdbe57a
5 changes: 5 additions & 0 deletions include/cliffordsynthesis/Utils.hpp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads-up: I personally despise Utils files, so please feel free to disagree on this, but I do not think the functionality here should be in a separate file.
All of this can simply go into the GateSet class/file. The isPauli method can even be used there to simplify some if condition.

Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//
// This file is part of the MQT QMAP library released under the MIT license.
// See README.md or go to https://github.com/cda-tum/qmap for more information.
//

#pragma once

#include "cliffordsynthesis/GateSet.hpp"
7 changes: 4 additions & 3 deletions include/cliffordsynthesis/encoding/GateEncoder.hpp
Original file line number Diff line number Diff line change
@@ -26,9 +26,10 @@ class GateEncoder {
const std::size_t timestepLimit,
TableauEncoder::Variables* tableauVars,
std::shared_ptr<logicbase::LogicBlock> logicBlock,
GateSet singleQGates)
GateSet singleQGates,
bool ignorePhase = false)
: N(nQubits), S(tableauSize), T(timestepLimit), tvars(tableauVars),
lb(std::move(logicBlock)), singleQubitGates(std::move(singleQGates)) {
lb(std::move(logicBlock)), singleQubitGates(std::move(singleQGates)), ignoreRChanges(ignorePhase) {
if (!singleQGates.isValidGateSet()) {
throw qc::QFRException("Invalid gate set");
}
@@ -90,7 +91,7 @@ class GateEncoder {
// the gates that are used
GateSet singleQubitGates;

bool
bool ignoreRChanges{false};

using TransformationFamily =
std::pair<logicbase::LogicTerm, std::vector<qc::OpType>>;
2 changes: 2 additions & 0 deletions include/cliffordsynthesis/encoding/SATEncoder.hpp
Original file line number Diff line number Diff line change
@@ -59,6 +59,8 @@ class SATEncoder {
SolverParameterMap solverParameters = {};

GateSet gateSet = {};

bool ignoreRChanges = false;
};

SATEncoder() = default;
7 changes: 5 additions & 2 deletions include/cliffordsynthesis/encoding/TableauEncoder.hpp
Original file line number Diff line number Diff line change
@@ -19,9 +19,10 @@ class TableauEncoder {
TableauEncoder() = default;
TableauEncoder(const std::size_t nQubits, const std::size_t tableauSize,
const std::size_t timestepLimit,
std::shared_ptr<logicbase::LogicBlock> logicBlock)
std::shared_ptr<logicbase::LogicBlock> logicBlock,
bool ignorePhase=false)
: N(nQubits), S(tableauSize), T(timestepLimit),
lb(std::move(logicBlock)) {}
lb(std::move(logicBlock)), ignoreR(ignorePhase) {}

struct Variables {
// variables for the X parts of the tableaus
@@ -76,5 +77,7 @@ class TableauEncoder {

// the logic block to use
std::shared_ptr<logicbase::LogicBlock> lb{};

bool ignoreR = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am adding this here another time just to be sure: Consistent naming of this option throughout the library would greatly benefit clarity.

};
} // namespace cs::encoding
8 changes: 6 additions & 2 deletions src/cliffordsynthesis/encoding/GateEncoder.cpp
Original file line number Diff line number Diff line change
@@ -189,7 +189,9 @@ void GateEncoder::assertSingleQubitGateConstraints(std::size_t pos) {
DEBUG() << "Asserting gates on " << q;
assertZConstraints(pos, q);
assertXConstraints(pos, q);
if (! ignoreRChanges){
assertRConstraints(pos, q);
}
}
}

@@ -200,8 +202,10 @@ void GateEncoder::assertTwoQubitGateConstraints(std::size_t pos) {
if (ctrl == trgt) {
continue;
}
const auto changes = createTwoQubitGateConstraint(pos, ctrl, trgt) &&
createTwoQubitRConstraint(pos, ctrl, trgt);
auto changes = createTwoQubitGateConstraint(pos, ctrl, trgt);
if(!ignoreRChanges){
changes = changes && createTwoQubitRConstraint(pos, ctrl, trgt);
}
lb->assertFormula(LogicTerm::implies(twoQubitGates[ctrl][trgt], changes));
DEBUG() << "Asserting CNOT on " << ctrl << " and " << trgt;
}
12 changes: 9 additions & 3 deletions src/cliffordsynthesis/encoding/MultiGateEncoder.cpp
Original file line number Diff line number Diff line change
@@ -49,12 +49,18 @@ void encoding::MultiGateEncoder::assertGateConstraints() {
xorHelpers = logicbase::LogicMatrix{T};
for (std::size_t t = 0U; t < T; ++t) {
TRACE() << "Asserting gate constraints at time " << t;
rChanges = tvars->r[t];
splitXorR(tvars->r[t], t);
if(!ignoreRChanges){
rChanges = tvars->r[t];
splitXorR(tvars->r[t], t);
}
assertSingleQubitGateConstraints(t);
assertTwoQubitGateConstraints(t);
TRACE() << "Asserting r changes at time " << t;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logging message should be moved to the underlying if

lb->assertFormula(tvars->r[t + 1] == xorHelpers[t].back());

if(!ignoreRChanges){
lb->assertFormula(tvars->r[t + 1] == xorHelpers[t].back());
}

}
}

8 changes: 4 additions & 4 deletions src/cliffordsynthesis/encoding/SATEncoder.cpp
Original file line number Diff line number Diff line change
@@ -55,17 +55,17 @@ void SATEncoder::createFormulation() {
? 2U * N
: N;

tableauEncoder = std::make_shared<TableauEncoder>(N, s, T, lb);
tableauEncoder = std::make_shared<TableauEncoder>(N, s, T, lb, config.ignoreRChanges);
tableauEncoder->createTableauVariables();
tableauEncoder->assertTableau(*config.initialTableau, 0U);
tableauEncoder->assertTableau(*config.targetTableau, T);

if (config.useMultiGateEncoding) {
gateEncoder = std::make_shared<MultiGateEncoder>(
N, s, T, tableauEncoder->getVariables(), lb, config.gateSet);
N, s, T, tableauEncoder->getVariables(), lb, config.gateSet, config.ignoreRChanges);
} else {
gateEncoder = std::make_shared<SingleGateEncoder>(
N, s, T, tableauEncoder->getVariables(), lb, config.gateSet);
N, s, T, tableauEncoder->getVariables(), lb, config.gateSet, config.ignoreRChanges);
}
gateEncoder->createSingleQubitGateVariables();
gateEncoder->createTwoQubitGateVariables();
@@ -76,7 +76,7 @@ void SATEncoder::createFormulation() {
}

objectiveEncoder = std::make_shared<ObjectiveEncoder>(
N, T, gateEncoder->getVariables(), lb, config.gateSet);
N, T, gateEncoder->getVariables(), lb, config.gateSet);

if (config.gateLimit.has_value()) {
objectiveEncoder->limitGateCount(*config.gateLimit, std::less_equal{});
25 changes: 16 additions & 9 deletions src/cliffordsynthesis/encoding/TableauEncoder.cpp
Original file line number Diff line number Diff line change
@@ -17,7 +17,9 @@ void TableauEncoder::createTableauVariables() {
DEBUG() << "Creating tableau variables.";
vars.x.reserve(T);
vars.z.reserve(T);
vars.r.reserve(T);
if(!ignoreR){
vars.r.reserve(T);
}
for (std::size_t t = 0U; t <= T; ++t) {
auto& x = vars.x.emplace_back();
auto& z = vars.z.emplace_back();
@@ -33,9 +35,11 @@ void TableauEncoder::createTableauVariables() {
TRACE() << "Creating variable " << zName;
z.emplace_back(lb->makeVariable(zName, CType::BITVECTOR, n));
}
const std::string rName = "r_" + std::to_string(t);
TRACE() << "Creating variable " << rName;
vars.r.emplace_back(lb->makeVariable(rName, CType::BITVECTOR, n));
if(!ignoreR){
const std::string rName = "r_" + std::to_string(t);
TRACE() << "Creating variable " << rName;
vars.r.emplace_back(lb->makeVariable(rName, CType::BITVECTOR, n));
}
}
}

@@ -53,8 +57,10 @@ void TableauEncoder::assertTableau(const Tableau& tableau,
lb->assertFormula(vars.z[t][a] == LogicTerm(targetZ, n));
}

const auto targetR = tableau.getBVFrom(2U * N);
lb->assertFormula(vars.r[t] == LogicTerm(targetR, n));
if(!ignoreR){
const auto targetR = tableau.getBVFrom(2U * N);
lb->assertFormula(vars.r[t] == LogicTerm(targetR, n));
}
}

void TableauEncoder::extractTableauFromModel(Results& results,
@@ -67,9 +73,10 @@ void TableauEncoder::extractTableauFromModel(Results& results,
const auto bvz = model.getBitvectorValue(vars.z[t][i], lb.get());
tableau.populateTableauFrom(bvz, S, i + N);
}
const auto bvr = model.getBitvectorValue(vars.r[t], lb.get());
tableau.populateTableauFrom(bvr, S, 2 * N);

if(!ignoreR){
const auto bvr = model.getBitvectorValue(vars.r[t], lb.get());
tableau.populateTableauFrom(bvr, S, 2 * N);
}
results.setResultTableau(tableau);
}