Skip to content

Commit

Permalink
Output revamp (#117)
Browse files Browse the repository at this point in the history
* upconverted error messages to exceptions to address issues #28 and #62
* overhaul of exceptions for c++ and python
* added support for python logging module
* added an interactive mode (default False) which can be enabled to
  emulate older versions (capturing keyboard interrupts and dumping
  output to stdout/stderr rather than logging)

Note: we abandoned unit testing of keyboard interrupts on windows/all and
osx/py38 for various reasons.  Hopefully this is temporary.
  • Loading branch information
boothby authored Mar 30, 2020
1 parent 87bda74 commit 6dcee69
Show file tree
Hide file tree
Showing 15 changed files with 414 additions and 241 deletions.
63 changes: 31 additions & 32 deletions include/chain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
namespace find_embedding {

#ifdef CPPDEBUG
#define DIAGNOSE2(other, X) \
diagnostic(X); \
other.diagnostic(X);
#define DIAGNOSE(X) diagnostic(X);
#define DIAGNOSE_CHAINS(other) \
diagnostic(); \
other.diagnostic();
#define DIAGNOSE_CHAIN() diagnostic();
#else
#define DIAGNOSE2(other, X)
#define DIAGNOSE(X)
#define DIAGNOSE_CHAINS(other)
#define DIAGNOSE_CHAIN()
#endif

//! This class stores chains for embeddings, and performs qubit-use
Expand Down Expand Up @@ -81,7 +81,7 @@ class chain {
minorminer_assert(0 <= q && q < qubit_weight.size());
qubit_weight[q]++;
}
DIAGNOSE("operator=vector");
DIAGNOSE_CHAIN();
return *this;
}

Expand All @@ -91,7 +91,7 @@ class chain {
data = c.data;
for (auto &q : c) qubit_weight[q]++;
links = c.links;
DIAGNOSE("operator=chain");
DIAGNOSE_CHAIN();
return *this;
}

Expand Down Expand Up @@ -119,7 +119,7 @@ class chain {
links[x] = q;

retrieve(q).second++;
DIAGNOSE("set_link");
DIAGNOSE_CHAIN();
}

//! discard and return the linking qubit for `x`, or -1 if that link is not set
Expand All @@ -132,7 +132,7 @@ class chain {
retrieve(q).second--;
links.erase(z);
}
DIAGNOSE("drop_link");
DIAGNOSE_CHAIN();
return q;
}

Expand All @@ -144,15 +144,15 @@ class chain {
links.emplace(label, q);
data.emplace(q, pair<int, int>(q, 2));
qubit_weight[q]++;
DIAGNOSE("set_root");
DIAGNOSE_CHAIN();
}

//! empty this data structure
inline void clear() {
for (auto &q : *this) qubit_weight[q]--;
data.clear();
links.clear();
DIAGNOSE("clear");
DIAGNOSE_CHAIN();
}

//! add the qubit `q` as a leaf, with `parent` as its parent
Expand All @@ -162,7 +162,7 @@ class chain {
data.emplace(q, pair<int, int>(parent, 0));
qubit_weight[q]++;
retrieve(parent).second++;
DIAGNOSE("add_leaf");
DIAGNOSE_CHAIN();
}

//! try to delete the qubit `q` from this chain, and keep
Expand All @@ -176,7 +176,7 @@ class chain {
p = trim_leaf(q);
}
minorminer_assert(data.count(q) == 1);
DIAGNOSE("trim_branch");
DIAGNOSE_CHAIN();
return q;
}

Expand All @@ -192,7 +192,7 @@ class chain {
data.erase(z);
q = p.first;
}
DIAGNOSE("trim_leaf");
DIAGNOSE_CHAIN();
return q;
}

Expand All @@ -216,7 +216,7 @@ class chain {
Q.second--;
P.second++;
minorminer_assert(parent(q) == p);
DIAGNOSE("adopt");
DIAGNOSE_CHAIN();
}

//! return the number of references that `this` makes to the qubit
Expand Down Expand Up @@ -244,7 +244,7 @@ class chain {
for (auto &q : *this) qubit_weight[q]--;
keep.data.swap(data);
minorminer_assert(size() == 0);
DIAGNOSE("freeze");
DIAGNOSE_CHAIN();
return keep.data.size();
}

Expand All @@ -264,7 +264,7 @@ class chain {
others[v].set_link(label, v_p.second);
}
}
DIAGNOSE("thaw");
DIAGNOSE_CHAIN();
}

//! assumes `this` and `other` have links for eachother's labels
Expand Down Expand Up @@ -307,7 +307,7 @@ class chain {

set_link(other.label, q);
other.set_link(label, p);
DIAGNOSE2(other, "steal");
DIAGNOSE_CHAINS(other);
}

//! link this chain to another, following the path
Expand Down Expand Up @@ -337,7 +337,7 @@ class chain {
minorminer_assert(count(q) == 1);
set_link(other.label, q);
other.set_link(label, p);
DIAGNOSE2(other, "link_path");
DIAGNOSE_CHAINS(other);
}

class iterator {
Expand All @@ -358,20 +358,19 @@ class chain {
iterator end() const { return iterator(data.end()); };

//! run the diagnostic, and if it fails, report the failure to the user
//! and throw -1. the `last_op` argument is used in the error message
inline void diagnostic(char *last_op) {
//! and throw a CorruptEmbeddingException. the `last_op` argument is
//! used in the error message
inline void diagnostic() {
#ifdef CPPDEBUG
if (belay_diagnostic) return;
#endif
int r = run_diagnostic();

if (r) {
std::cout << "chain diagnostic failures on var " << label << ":";
if (r & 1) std::cout << " (parent containment)";
if (r & 2) std::cout << " (refcount)";

std::cout << ". last operation was " << last_op << std::endl;
throw - 1;
switch (run_diagnostic()) {
case 1:
throw CorruptEmbeddingException("Qubit containment errors found in chain diagnostics.");
case 2:
throw CorruptEmbeddingException("Parent errors found in chain diagnostics.");
case 3:
throw CorruptEmbeddingException("Multiple errors found in chain diagnostics.");
}
}

Expand Down Expand Up @@ -405,4 +404,4 @@ class chain {
//! non-const unsafe data accessor
inline pair<int, int> &retrieve(int q) { return (*data.find(q)).second; }
};
}
} // namespace find_embedding
2 changes: 0 additions & 2 deletions include/debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
#endif
#include <assert.h>
#define minorminer_assert(X) assert(X)
#define ONDEBUG(X) X
#else
#ifndef minorminer_assert
#define minorminer_assert(X)
#define ONDEBUG(X) /*X*/
#endif
#endif
37 changes: 18 additions & 19 deletions include/embedding.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
namespace find_embedding {

#ifdef CPPDEBUG
#define DIAGNOSE(X) long_diagnostic(X);
#define DIAGNOSE_EMB(X) long_diagnostic(X);
#else
#define DIAGNOSE(X)
#define DIAGNOSE_EMB(X)
#endif

//! This class is how we represent and manipulate embedding objects, using as
Expand Down Expand Up @@ -60,7 +60,7 @@ class embedding {
var_embedding(),
frozen() {
for (int q = 0; q < num_vars + num_fixed; q++) var_embedding.emplace_back(qub_weight, q);
DIAGNOSE("post base_construct");
DIAGNOSE_EMB("post base_construct");
}

//! constructor for an initial embedding: accepts fixed and
Expand Down Expand Up @@ -96,13 +96,13 @@ class embedding {
for (auto &u : ep.var_neighbors(v))
if (u > v) linkup(v, u);
}
DIAGNOSE("post construct");
DIAGNOSE_EMB("post construct");
}

//! copy the data from `other.var_embedding` into `this.var_embedding`
embedding<embedding_problem_t> &operator=(const embedding<embedding_problem_t> &other) {
if (this != &other) var_embedding = other.var_embedding;
DIAGNOSE("operator=");
DIAGNOSE_EMB("operator=");
return *this;
}

Expand Down Expand Up @@ -132,7 +132,7 @@ class embedding {
inline void set_chain(const int u, const vector<int> &incoming) {
// remove the current chain and account for its qubits
var_embedding[u] = incoming;
DIAGNOSE("set_chain");
DIAGNOSE_EMB("set_chain");
}

//! Permanently assign a chain for variable u.
Expand All @@ -147,7 +147,7 @@ class embedding {
}
#endif
var_embedding[u] = incoming;
DIAGNOSE("fix_chain");
DIAGNOSE_EMB("fix_chain");
}

//! check if `this` and `other` have the same chains (up to qubit
Expand All @@ -170,7 +170,7 @@ class embedding {
for (auto &v : ep.var_neighbors(u))
if (chainsize(v)) var_embedding[u].link_path(var_embedding[v], q, parents[v]);

DIAGNOSE("construct_chain")
DIAGNOSE_EMB("construct_chain")
}

//! construct the chain for `u`, rooted at `q`. for the first neighbor `v` of `u`,
Expand Down Expand Up @@ -200,7 +200,7 @@ class embedding {
var_embedding[u].link_path(var_embedding[v], qv, parents[v]);
}
}
DIAGNOSE("construct_chain_steiner")
DIAGNOSE_EMB("construct_chain_steiner")
}

//! distribute path segments to the neighboring chains -- path segments are the qubits
Expand All @@ -211,15 +211,15 @@ class embedding {
void flip_back(int u, const int target_chainsize) {
for (auto &v : ep.var_neighbors(u))
if (chainsize(v) && !(ep.fixed(v))) var_embedding[v].steal(var_embedding[u], ep, target_chainsize);
DIAGNOSE("flip_back")
DIAGNOSE_EMB("flip_back")
}

//! short tearout procedure
//! blank out the chain, its linking qubits, and account for the qubits being freed
void tear_out(int u) {
var_embedding[u].clear();
for (auto &v : ep.var_neighbors(u)) var_embedding[v].drop_link(u);
DIAGNOSE("tear_out")
DIAGNOSE_EMB("tear_out")
}

//! undo-able tearout procedure. similar to `tear_out(u)`, but can be undone with
Expand All @@ -230,7 +230,7 @@ class embedding {
//! `freeze_out(u)`. returns the size of the chain being frozen
int freeze_out(int u) {
int size = var_embedding[u].freeze(var_embedding, frozen);
DIAGNOSE("freeze_out")
DIAGNOSE_EMB("freeze_out")
return size;
}

Expand All @@ -241,7 +241,7 @@ class embedding {
//! `freeze_out(u)`)
void thaw_back(int u) {
var_embedding[u].thaw(var_embedding, frozen);
DIAGNOSE("thaw_back")
DIAGNOSE_EMB("thaw_back")
}

//! grow the chain for `u`, stealing all available qubits from neighboring variables
Expand All @@ -252,7 +252,7 @@ class embedding {
if (var_embedding[v].get_link(u) == -1) continue;
var_embedding[u].steal(var_embedding[v], ep);
}
DIAGNOSE("steal_all")
DIAGNOSE_EMB("steal_all")
}

//! compute statistics for this embedding and return `1` if no chains are overlapping
Expand Down Expand Up @@ -354,7 +354,7 @@ class embedding {
}

//! run a long diagnostic, and if debugging is enabled, record `current_state` so that the
//! error message has a little more context. if an error is found, throw -1
//! error message has a little more context. if an error is found, throw a CorruptEmbeddingException
void long_diagnostic(char *current_state) {
run_long_diagnostic(current_state);
#ifdef CPPDEBUG
Expand Down Expand Up @@ -530,14 +530,13 @@ class embedding {
}

if (err) {
ep.error("errors found in data structure, current state is '%s'. quitting\n", current_state);
#ifdef CPPDEBUG
if (last_diagnostic != nullptr) ep.debug("last state was %s\n", last_diagnostic);
#endif
ep.error("errors found in data structure, current state is '%s'. quitting\n", current_state);
print();
std::flush(std::cout);
throw - 1;
throw CorruptEmbeddingException("Errors found in embedding data structure. Cannot recover.");
}
}
};
}
} // namespace find_embedding
Loading

0 comments on commit 6dcee69

Please sign in to comment.