Skip to content

Commit

Permalink
🔥 Remove Snapshot and ShowProbabilities instructions from MQT Core (#393
Browse files Browse the repository at this point in the history
)
  • Loading branch information
burgholzer authored Aug 9, 2023
1 parent da83c0b commit 5982ba7
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 155 deletions.
3 changes: 1 addition & 2 deletions include/dd/FunctionalityConstruction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ inline void dumpTensorNetwork(std::ostream& of, const QuantumComputation& qc) {
auto dd = std::make_unique<dd::Package<>>(qc.getNqubits());
for (const auto& op : qc) {
const auto type = op->getType();
if (op != qc.front() && (type != Measure && type != Barrier &&
type != ShowProbabilities && type != Snapshot)) {
if (op != qc.front() && (type != Measure && type != Barrier)) {
of << ",\n";
}
dumpTensor(op.get(), of, inds, gateIdx, dd);
Expand Down
3 changes: 1 addition & 2 deletions include/dd/Operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,7 @@ qc::MatrixDD getDD(const qc::Operation* op,
return dd->makeIdent(nqubits);
}

if (type == qc::ShowProbabilities || type == qc::Barrier ||
type == qc::Snapshot) {
if (type == qc::Barrier) {
return dd->makeIdent(nqubits);
}

Expand Down
23 changes: 2 additions & 21 deletions include/operations/NonUnitaryOperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,15 @@ class NonUnitaryOperation final : public Operation {
void printMeasurement(std::ostream& os, const std::vector<Qubit>& q,
const std::vector<Bit>& c,
const Permutation& permutation) const;
void printResetBarrierOrSnapshot(std::ostream& os,
const std::vector<Qubit>& q,
const Permutation& permutation) const;
void printResetOrBarrier(std::ostream& os, const std::vector<Qubit>& q,
const Permutation& permutation) const;

public:
// Measurement constructor
NonUnitaryOperation(std::size_t nq, std::vector<Qubit> qubitRegister,
std::vector<Bit> classicalRegister);
NonUnitaryOperation(std::size_t nq, Qubit qubit, Bit cbit);

// Snapshot constructor
NonUnitaryOperation(std::size_t nq, const std::vector<Qubit>& qubitRegister,
std::size_t n);

// ShowProbabilities constructor
explicit NonUnitaryOperation(const std::size_t nq) {
nqubits = nq;
type = ShowProbabilities;
}

// General constructor
NonUnitaryOperation(std::size_t nq, const std::vector<Qubit>& qubitRegister,
OpType op = Reset);
Expand All @@ -46,14 +35,6 @@ class NonUnitaryOperation final : public Operation {
return std::make_unique<NonUnitaryOperation>(getNqubits(), getTargets(),
getClassics());
}
if (getType() == qc::Snapshot) {
return std::make_unique<NonUnitaryOperation>(
getNqubits(), getTargets(),
static_cast<std::size_t>(getParameter().at(0)));
}
if (getType() == qc::ShowProbabilities) {
return std::make_unique<NonUnitaryOperation>(getNqubits());
}
return std::make_unique<NonUnitaryOperation>(getNqubits(), getTargets(),
getType());
}
Expand Down
8 changes: 0 additions & 8 deletions include/operations/OpType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ enum OpType : std::uint8_t {
// Non Unitary Operations
Measure,
Reset,
Snapshot,
ShowProbabilities,
Barrier,
Teleportation,
// Classically-controlled Operation
Expand Down Expand Up @@ -136,10 +134,6 @@ inline std::string toString(const OpType& opType) {
return "measure";
case Reset:
return "reset";
case Snapshot:
return "snapshot";
case ShowProbabilities:
return "show probabilities";
case Barrier:
return "barrier";
case Teleportation:
Expand Down Expand Up @@ -241,8 +235,6 @@ const inline static std::unordered_map<std::string, qc::OpType>
{"xx_plus_yy", OpType::XXplusYY},
{"measure", OpType::Measure},
{"reset", OpType::Reset},
{"snapshot", OpType::Snapshot},
{"show probabilities", OpType::ShowProbabilities},
{"barrier", OpType::Barrier},
{"teleportation", OpType::Teleportation},
{"classic controlled", OpType::ClassicControlled},
Expand Down
16 changes: 6 additions & 10 deletions src/CircuitOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,7 @@ void CircuitOptimizer::removeDiagonalGatesBeforeMeasureRecursive(
}
}
auto* op = (*it)->get();
if (op->getType() == Barrier || op->getType() == Snapshot ||
op->getType() == ShowProbabilities) {
if (op->getType() == Barrier) {
++it;
} else if (op->isStandardOperation()) {
// try removing gate and upon success increase all corresponding iterators
Expand Down Expand Up @@ -548,8 +547,7 @@ void CircuitOptimizer::removeFinalMeasurementsRecursive(
++(dagIterators.at(target));
}
}
} else if (op->getType() == Barrier || op->getType() == Snapshot ||
op->getType() == ShowProbabilities) {
} else if (op->getType() == Barrier) {
for (const auto& target : op->getTargets()) {
if (dagIterators.at(target) == dag.at(target).rend()) {
break;
Expand Down Expand Up @@ -1096,12 +1094,10 @@ void CircuitOptimizer::reorderOperations(QuantumComputation& qc) {
// warning for classically controlled operations
if (op->getType() == ClassicControlled) {
std::cerr << "Caution! Reordering operations might not work if the "
"circuit contains classically controlled operations"
<< std::endl;
"circuit contains classically controlled operations\n";
}

if (op->getType() == Barrier || op->getType() == Snapshot ||
op->getType() == ShowProbabilities) {
if (op->getType() == Barrier) {
++it;
continue;
}
Expand Down Expand Up @@ -1159,7 +1155,7 @@ void CircuitOptimizer::printDAG(const DAG& dag) {
std::cout << std::hex << (*op).get() << std::dec << "("
<< toString((*op)->getType()) << ") - ";
}
std::cout << std::endl;
std::cout << "\n";
}
}
void CircuitOptimizer::printDAG(const DAG& dag, const DAGIterators& iterators) {
Expand All @@ -1169,7 +1165,7 @@ void CircuitOptimizer::printDAG(const DAG& dag, const DAGIterators& iterators) {
std::cout << std::hex << (**it).get() << std::dec << "("
<< toString((**it)->getType()) << ") - ";
}
std::cout << std::endl;
std::cout << "\n";
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/dd/Operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,10 @@ void dumpTensor(qc::Operation* op, std::ostream& of,
}
dumpTensor(operation.get(), of, inds, gateIdx, dd);
}
} else if (type == qc::Barrier || type == qc::ShowProbabilities ||
type == qc::Snapshot) {
} else if (type == qc::Barrier) {
return;
} else if (type == qc::Measure) {
std::clog << "Skipping measurement in tensor dump." << std::endl;
std::clog << "Skipping measurement in tensor dump.\n";
} else {
throw qc::QFRException("Dumping of tensors is currently only supported for "
"StandardOperations.");
Expand Down
117 changes: 29 additions & 88 deletions src/operations/NonUnitaryOperation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ NonUnitaryOperation::NonUnitaryOperation(const std::size_t nq,
Operation::setName();
}

// Snapshot constructor
NonUnitaryOperation::NonUnitaryOperation(
const std::size_t nq, const std::vector<Qubit>& qubitRegister,
const std::size_t n)
: NonUnitaryOperation(nq, qubitRegister, Snapshot) {
parameter.emplace_back(static_cast<fp>(n));
}

// General constructor
NonUnitaryOperation::NonUnitaryOperation(
const std::size_t nq, const std::vector<Qubit>& qubitRegister, OpType op) {
Expand All @@ -61,15 +53,9 @@ std::ostream& NonUnitaryOperation::printNonUnitary(
break;
case Reset:
case Barrier:
case Snapshot:
printResetBarrierOrSnapshot(os, q, permutation);
break;
case ShowProbabilities:
os << name;
printResetOrBarrier(os, q, permutation);
break;
default:
std::cerr << "Non-unitary operation with invalid type " << type
<< " detected. Proceed with caution!" << std::endl;
break;
}
return os;
Expand All @@ -78,59 +64,25 @@ std::ostream& NonUnitaryOperation::printNonUnitary(
void NonUnitaryOperation::dumpOpenQASM(std::ostream& of,
const RegisterNames& qreg,
const RegisterNames& creg) const {
auto classicsIt = classics.cbegin();
switch (type) {
case Measure:
if (isWholeQubitRegister(qreg, qubits.front(), qubits.back()) &&
isWholeQubitRegister(qreg, classics.front(), classics.back())) {
of << "measure " << qreg[qubits.front()].first << " -> "
<< creg[classics.front()].first << ";" << std::endl;
} else {
for (const auto& c : qubits) {
of << "measure " << qreg[c].second << " -> " << creg[*classicsIt].second
<< ";" << std::endl;
++classicsIt;
}
const auto& qubitArgs = getTargets();
if (isWholeQubitRegister(qreg, qubitArgs.front(), qubitArgs.back())) {
of << toString(type) << " " << qreg[qubitArgs.front()].first;
if (type == Measure) {
of << " -> ";
assert(isWholeQubitRegister(creg, classics.front(), classics.back()));
of << creg[classics.front()].first;
}
break;
case Reset:
if (isWholeQubitRegister(qreg, targets.front(), targets.back())) {
of << "reset " << qreg[targets.front()].first << ";" << std::endl;
} else {
for (const auto& target : targets) {
of << "reset " << qreg[target].second << ";" << std::endl;
}
}
break;
case Snapshot:
if (!targets.empty()) {
of << "snapshot(" << parameter[0] << ") ";

for (unsigned int q = 0; q < targets.size(); ++q) {
if (q > 0) {
of << ", ";
}
of << qreg[targets[q]].second;
}
of << ";" << std::endl;
}
break;
case ShowProbabilities:
of << "show_probabilities;" << std::endl;
break;
case Barrier:
if (isWholeQubitRegister(qreg, targets.front(), targets.back())) {
of << "barrier " << qreg[targets.front()].first << ";" << std::endl;
} else {
for (const auto& target : targets) {
of << "barrier " << qreg[target].second << ";" << std::endl;
}
of << ";\n";
return;
}
auto classicsIt = classics.cbegin();
for (const auto& q : qubitArgs) {
of << toString(type) << " " << qreg[q].second;
if (type == Measure) {
of << " -> " << creg[*classicsIt].second;
++classicsIt;
}
break;
default:
std::cerr << "Non-unitary operation with invalid type " << type
<< " detected. Proceed with caution!" << std::endl;
break;
of << ";\n";
}
}

Expand Down Expand Up @@ -237,7 +189,7 @@ void NonUnitaryOperation::printMeasurement(
}
}

void NonUnitaryOperation::printResetBarrierOrSnapshot(
void NonUnitaryOperation::printResetOrBarrier(
std::ostream& os, const std::vector<Qubit>& q,
const Permutation& permutation) const {
auto qubitIt = q.cbegin();
Expand All @@ -247,17 +199,13 @@ void NonUnitaryOperation::printResetBarrierOrSnapshot(
if (qubitIt != q.cend() && *qubitIt == i) {
if (type == Reset) {
os << "\033[31m"
<< "r\t"
<< "\033[0m";
} else if (type == Barrier) {
os << "\033[32m"
<< "b\t"
<< "\033[0m";
<< "r";
} else {
os << "\033[33m"
<< "s\t"
<< "\033[0m";
assert(type == Barrier);
os << "\033[32m"
<< "b";
}
os << "\t\033[0m";
++qubitIt;
} else {
os << "|\t";
Expand All @@ -268,25 +216,18 @@ void NonUnitaryOperation::printResetBarrierOrSnapshot(
if (qubitIt != q.cend() && *qubitIt == physical) {
if (type == Reset) {
os << "\033[31m"
<< "r\t"
<< "\033[0m";
} else if (type == Barrier) {
os << "\033[32m"
<< "b\t"
<< "\033[0m";
<< "r";
} else {
os << "\033[33m"
<< "s\t"
<< "\033[0m";
assert(type == Barrier);
os << "\033[32m"
<< "b";
}
os << "\t\033[0m";
++qubitIt;
} else {
os << "|\t";
}
}
}
if (type == Snapshot) {
os << "\tp: (" << q.size() << ") (" << parameter[0] << ")";
}
}
} // namespace qc
21 changes: 2 additions & 19 deletions src/parsers/QASMParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,32 +98,15 @@ void qc::QuantumComputation::importOpenQASM(std::istream& is) {
p.scan();
p.check(Token::Kind::Lpar);
p.check(Token::Kind::Nninteger);
auto n = static_cast<std::size_t>(p.t.val);
p.check(Token::Kind::Rpar);

std::vector<qc::QuantumRegister> arguments{};
p.argList(arguments);

p.check(Token::Kind::Semicolon);

for (auto& arg : arguments) {
if (arg.second != 1) {
p.error("Error in snapshot: arguments must be qubits");
}
}

Targets qubits{};
qubits.reserve(arguments.size());
for (auto& arg : arguments) {
qubits.emplace_back(arg.first);
}

emplace_back<NonUnitaryOperation>(nqubits, qubits, n);
// Snapshots have no meaning for MQT Core and are ignored.
} else if (p.sym == Token::Kind::Probabilities) {
// show probabilities statement
emplace_back<NonUnitaryOperation>(nqubits);
p.scan();
p.check(Token::Kind::Semicolon);
// Show probabilities has no meaning for MQT Core and is ignored.
} else if (p.sym == Token::Kind::Comment) {
// comment
p.scan();
Expand Down
2 changes: 0 additions & 2 deletions test/unittests/test_qfr_functionality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,8 +777,6 @@ TEST_F(QFRFunctionality, cloningDifferentOperations) {
comp.h(0);
qc.emplace_back(comp.asOperation());
qc.classicControlled(qc::X, 0, qc.getCregs().at("c"), 1);
qc.emplace_back<NonUnitaryOperation>(qc.getNqubits(),
std::vector<Qubit>{0, 1}, 1);

auto qcCloned = qc.clone();
ASSERT_EQ(qc.size(), qcCloned.size());
Expand Down

1 comment on commit 5982ba7

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

Cpp-Linter Report ✔️

No problems need attention.

Have any feedback or feature suggestions? Share it here.

Please sign in to comment.