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

Feature/TwoQubitEncoding #342

Closed
wants to merge 38 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5a32776
set the main structure
Jun 23, 2023
014f075
Merge branch 'main' into feature/avelsh
Jun 23, 2023
9c9256e
🎨 pre-commit fixes
pre-commit-ci[bot] Jun 23, 2023
a7822e0
add SQG and TQG encoding
Jul 8, 2023
59393a8
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 8, 2023
cdd566e
update comments
Jul 13, 2023
716b8a6
Merge remote-tracking branch 'origin/feature/avelsh' into feature/avelsh
Jul 13, 2023
499b06e
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 13, 2023
d283ef8
update according to comments, rename two qubit encoder
Jul 30, 2023
77cc2a5
Merge remote-tracking branch 'origin/feature/avelsh' into feature/avelsh
Jul 30, 2023
7c7d542
🎨 pre-commit fixes
pre-commit-ci[bot] Jul 30, 2023
9b0155a
correct asssertTwoQubitGateConstr
Aug 9, 2023
c9c1a44
Merge remote-tracking branch 'origin/feature/avelsh' into feature/avelsh
Aug 9, 2023
0266b24
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 9, 2023
122dd5d
fix two qubit encoding
Aug 14, 2023
1c0a309
rename from STDepth to TQDepth
Aug 14, 2023
7ca3ec7
sync with upstream
Aug 14, 2023
dfea58a
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 14, 2023
cf12bef
remove addIdentityGateToTQGVariables func
Aug 14, 2023
c095997
set a new func for founding of a two qubit depth
Aug 16, 2023
b6e11dd
Merge remote-tracking branch 'origin/feature/avelsh' into feature/avelsh
Aug 16, 2023
b128086
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 16, 2023
e37653d
fix founding of phase and set the last layer of paulis
Aug 21, 2023
8d1da8f
remove irrelevant tests
Aug 21, 2023
d042b11
set bindings and small fixes
Sep 5, 2023
92c5df6
optimize the using of variables
Sep 6, 2023
727fba8
Merge branch 'main' into feature/avelsh
pehamTom Sep 9, 2023
0425bfc
Merge remote-tracking branch 'avelsh/feature/avelsh' into feature/avelsh
pehamTom Sep 9, 2023
bd9af05
🎨 pre-commit fixes
pre-commit-ci[bot] Sep 9, 2023
3a4c206
Added parsing of target metric for two_qubit_depth
pehamTom Sep 9, 2023
247e276
Merge remote-tracking branch 'avelsh/feature/avelsh' into feature/avelsh
pehamTom Sep 9, 2023
1b39f2b
update according comments
Sep 10, 2023
c8bb1d6
Merge remote-tracking branch 'origin/feature/avelsh' into feature/avelsh
Sep 10, 2023
a80fd55
🎨 pre-commit fixes
pre-commit-ci[bot] Sep 10, 2023
098d4d6
set a new extra SQG layer
Sep 18, 2023
caafb46
🎨 pre-commit fixes
pre-commit-ci[bot] Sep 18, 2023
31090be
create a new func pauliGateToIndex
Oct 10, 2023
292052b
Merge remote-tracking branch 'origin/feature/avelsh' into feature/avelsh
Oct 10, 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
🎨 pre-commit fixes
pre-commit-ci[bot] committed Sep 18, 2023
commit caafb469295172ac31066a61e6479946fb3f1afe
4 changes: 2 additions & 2 deletions include/cliffordsynthesis/encoding/TwoQubitEncoder.hpp
Original file line number Diff line number Diff line change
@@ -53,8 +53,8 @@ class TwoQubitEncoder : public GateEncoder {
// extracting
void extractCircuitFromModel(Results& res, logicbase::Model& model) override;
void extractPauliGatesFromModel(logicbase::Model& model,
qc::QuantumComputation& qc,
std::size_t& nSingleQubitGates);
qc::QuantumComputation& qc,
std::size_t& nSingleQubitGates);

// helpers
void splitXorR(const logicbase::LogicTerm& changes, std::size_t pos);
56 changes: 27 additions & 29 deletions src/cliffordsynthesis/encoding/TwoQubitEncoder.cpp
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ using namespace logicbase;

void TwoQubitEncoder::createSingleQubitGateVariables() {
DEBUG() << "Creating single-qubit gate variables.";
vars.gS.reserve(T/2 + 1);
vars.gS.reserve(T / 2 + 1);
for (std::size_t t = 0U; t < T; t += 2U) {
auto& timeStep = vars.gS.emplace_back();
timeStep.reserve(SINGLE_QUBIT_GATES.size());
@@ -34,7 +34,7 @@ void TwoQubitEncoder::createSingleQubitGateVariables() {

void TwoQubitEncoder::createTwoQubitGateVariables() {
DEBUG() << "Creating two-qubit gate variables.";
vars.gC.reserve(T/2);
vars.gC.reserve(T / 2);
for (std::size_t t = 1U; t < T; t += 2U) {
auto& timeStep = vars.gC.emplace_back();
timeStep.reserve(N);
@@ -75,21 +75,21 @@ void encoding::TwoQubitEncoder::assertConsistency() const {
LogicVector singleQubitGateVariables{};
LogicVector twoQubitGateVariables{};

vars.collectSingleQubitGateVariables(t/2, q, singleQubitGateVariables);
vars.collectSingleQubitGateVariables(t / 2, q, singleQubitGateVariables);
assertExactlyOne(singleQubitGateVariables);
IF_PLOG(plog::verbose) {
TRACE() << "Single Qubit Gate variables at time " << t
<< " and qubit " << q;
TRACE() << "Single Qubit Gate variables at time " << t << " and qubit "
<< q;
for (const auto& var : singleQubitGateVariables) {
TRACE() << var.getName();
}
}

vars.collectTwoQubitGateVariables(t/2, q, true, twoQubitGateVariables);
vars.collectTwoQubitGateVariables(t/2, q, false, twoQubitGateVariables);
vars.collectTwoQubitGateVariables(t / 2, q, true, twoQubitGateVariables);
vars.collectTwoQubitGateVariables(t / 2, q, false, twoQubitGateVariables);

// add a variable that will be treated as identity
twoQubitGateVariables.emplace_back(vars.gC[t/2][q][q]);
twoQubitGateVariables.emplace_back(vars.gC[t / 2][q][q]);

assertExactlyOne(twoQubitGateVariables);
IF_PLOG(plog::verbose) {
@@ -107,7 +107,7 @@ void encoding::TwoQubitEncoder::assertConsistency() const {
for (std::size_t q = 0U; q < N; ++q) {
LogicVector pauliGateVariables{};
LogicVector singleQubitGateVariables{};
vars.collectSingleQubitGateVariables(T/2, q, singleQubitGateVariables);
vars.collectSingleQubitGateVariables(T / 2, q, singleQubitGateVariables);
assertExactlyOne(singleQubitGateVariables);
IF_PLOG(plog::verbose) {
TRACE() << "Single Qubit Gate variables at time " << T - 1
@@ -120,8 +120,8 @@ void encoding::TwoQubitEncoder::assertConsistency() const {
collectPauliGateVariables(q, pauliGateVariables);
assertExactlyOne(pauliGateVariables);
IF_PLOG(plog::verbose) {
TRACE() << "Pauli Qubit Gate variables at time " << T
<< " and qubit " << q;
TRACE() << "Pauli Qubit Gate variables at time " << T << " and qubit "
<< q;
for (const auto& var : pauliGateVariables) {
TRACE() << var.getName();
}
@@ -166,7 +166,7 @@ void TwoQubitEncoder::assertRConstraints(const std::size_t pos,
const std::size_t qubit) {
for (const auto gate : SINGLE_QUBIT_GATES) {
const auto& change =
LogicTerm::ite(vars.gS[pos/2][gateToIndex(gate)][qubit],
LogicTerm::ite(vars.gS[pos / 2][gateToIndex(gate)][qubit],
tvars->singleQubitRChange(pos, qubit, gate),
LogicTerm(0, static_cast<std::int16_t>(S)));
splitXorR(change, pos);
@@ -175,7 +175,7 @@ void TwoQubitEncoder::assertRConstraints(const std::size_t pos,

void encoding::TwoQubitEncoder::assertTwoQubitGateConstraints(
const std::size_t pos) {
const auto& twoQubitGates = vars.gC[pos/2];
const auto& twoQubitGates = vars.gC[pos / 2];
for (std::size_t ctrl = 0U; ctrl < N; ++ctrl) {
for (std::size_t trgt = 0U; trgt < N; ++trgt) {
if (ctrl == trgt) {
@@ -201,22 +201,21 @@ void encoding::TwoQubitEncoder::assertPauliGateConstraints(
const std::size_t pos) {
for (std::size_t q = 0U; q < N; ++q) {
for (const auto gate : PAULI_GATES) {
const auto& change =
LogicTerm::ite(gP[gateToIndex(gate)][q],
tvars->singleQubitRChange(pos, q, gate),
LogicTerm(0, static_cast<std::int16_t>(S)));
const auto& change = LogicTerm::ite(
gP[gateToIndex(gate)][q], tvars->singleQubitRChange(pos, q, gate),
LogicTerm(0, static_cast<std::int16_t>(S)));

splitXorR(change, pos);
}
lb->assertFormula(tvars->x[pos][q] == tvars->x[pos+1][q]);
lb->assertFormula(tvars->z[pos][q] == tvars->z[pos+1][q]);
lb->assertFormula(tvars->x[pos][q] == tvars->x[pos + 1][q]);
lb->assertFormula(tvars->z[pos][q] == tvars->z[pos + 1][q]);
Copy link
Member

Choose a reason for hiding this comment

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

Not necessary, but since only the phase is adjusted here, one could save on Tableau Variables.

}
}

void TwoQubitEncoder::assertGatesImplyTransform(
const std::size_t pos, const std::size_t qubit,
const std::vector<TransformationFamily>& transformations) {
const auto& singleQubitGates = vars.gS[pos/2];
const auto& singleQubitGates = vars.gS[pos / 2];
for (const auto& [transformation, gates] : transformations) {
auto gateOr = LogicTerm(false);
for (const auto& gate : gates) {
@@ -261,7 +260,7 @@ LogicTerm encoding::TwoQubitEncoder::createTwoQubitGateConstraint(
changes = changes && (tvars->z[pos + 1][trgt] == zTrgt);

const auto& newRChanges = LogicTerm::ite(
vars.gC[pos/2][ctrl][trgt], tvars->twoQubitRChange(pos, ctrl, trgt),
vars.gC[pos / 2][ctrl][trgt], tvars->twoQubitRChange(pos, ctrl, trgt),
LogicTerm(0, static_cast<std::int16_t>(S)));
splitXorR(newRChanges, pos);

@@ -273,12 +272,12 @@ void TwoQubitEncoder::extractCircuitFromModel(Results& res, Model& model) {
std::size_t nTwoQubitGates = 0U;

qc::QuantumComputation qc(N);
for (std::size_t t = 0; t < T/2; ++t) {
for (std::size_t t = 0; t < T / 2; ++t) {
extractSingleQubitGatesFromModel(t, model, qc, nSingleQubitGates);
extractTwoQubitGatesFromModel(t, model, qc, nTwoQubitGates);
}
//extract the last extra added SQG layer and the pauli layer
extractSingleQubitGatesFromModel(T/2, model, qc, nSingleQubitGates);
// extract the last extra added SQG layer and the pauli layer
extractSingleQubitGatesFromModel(T / 2, model, qc, nSingleQubitGates);
extractPauliGatesFromModel(model, qc, nSingleQubitGates);

res.setSingleQubitGates(nSingleQubitGates);
@@ -289,16 +288,14 @@ void TwoQubitEncoder::extractCircuitFromModel(Results& res, Model& model) {
}

void TwoQubitEncoder::extractPauliGatesFromModel(
Model& model, qc::QuantumComputation& qc,
std::size_t& nSingleQubitGates) {
Model& model, qc::QuantumComputation& qc, std::size_t& nSingleQubitGates) {
DEBUG() << "Extract pauli gates from model";
for (std::size_t q = 0U; q < N; ++q) {
for (const auto gate : PAULI_GATES) {
if (gate == qc::OpType::None) {
continue;
}
if (model.getBoolValue(gP[gateToIndex(gate)][q],
lb.get())) {
if (model.getBoolValue(gP[gateToIndex(gate)][q], lb.get())) {
qc.emplace_back<qc::StandardOperation>(N, q, gate);
++nSingleQubitGates;
DEBUG() << toString(gate) << "(" << q << ")";
@@ -309,7 +306,8 @@ void TwoQubitEncoder::extractPauliGatesFromModel(

// mock-functions
void TwoQubitEncoder::encodeSymmetryBreakingConstraints() {
DEBUG() << "Encoding symmetry breaking constraints IS NOT supported for the two qubit encoding.";
DEBUG() << "Encoding symmetry breaking constraints IS NOT supported for the "
"two qubit encoding.";
}

void TwoQubitEncoder::assertSingleQubitGateOrderConstraints(