Permalink
Browse files

replaced BOOST_VERIFY with checking and exceptions

  • Loading branch information...
aaalgo committed Jun 22, 2016
1 parent 73c2fce commit e8cbdbd92d5668c4589bce164dffdecfeb20d0d1
Showing with 60 additions and 34 deletions.
  1. +2 −2 index.cpp
  2. +13 −14 kgraph-data.h
  3. +7 −5 kgraph.cpp
  4. +18 −0 kgraph.h
  5. +20 −13 python/pykgraph.cpp
View
@@ -118,7 +118,7 @@ int main (int argc, char *argv[]) {
Matrix<value_type> data;
if (synthetic) {
if (!std::is_floating_point<value_type>::value) {
throw runtime_error("synthetic data not implemented for non-floating-point values.");
throw std::runtime_error("synthetic data not implemented for non-floating-point values.");
}
data.resize(synthetic, D);
cerr << "Generating synthetic data..." << endl;
@@ -137,7 +137,7 @@ int main (int argc, char *argv[]) {
}
if (noise != 0) {
if (!std::is_floating_point<value_type>::value) {
throw runtime_error("noise injection not implemented for non-floating-point value.");
throw std::runtime_error("noise injection not implemented for non-floating-point value.");
}
tr1::ranlux64_base_01 rng;
double sum = 0, sum2 = 0;
View
@@ -40,7 +40,6 @@ namespace kgraph {
using std::vector;
using std::runtime_error;
/// namespace for various distance metrics.
namespace metric {
@@ -149,7 +148,7 @@ namespace kgraph {
void load (const std::string &path, unsigned dim, unsigned skip = 0, unsigned gap = 0) {
std::ifstream is(path.c_str(), std::ios::binary);
BOOST_VERIFY(is);
if (!is) throw io_error(path);
is.seekg(0, std::ios::end);
size_t size = is.tellg();
size -= skip;
@@ -162,16 +161,16 @@ namespace kgraph {
is.read(&data[stride * i], sizeof(T) * dim);
is.seekg(gap, std::ios::cur);
}
BOOST_VERIFY(is);
if (!is) throw io_error(path);
}
void load_lshkit (std::string const &path) {
static const unsigned LSHKIT_HEADER = 3;
std::ifstream is(path.c_str(), std::ios::binary);
unsigned header[LSHKIT_HEADER]; /* entry size, row, col */
is.read((char *)header, sizeof header);
BOOST_VERIFY(is);
BOOST_VERIFY(header[0] == sizeof(T));
if (!is) throw io_error(path);
if (header[0] != sizeof(T)) throw io_error(path);
is.close();
unsigned D = header[2];
unsigned skip = LSHKIT_HEADER * sizeof(unsigned);
@@ -210,27 +209,27 @@ namespace kgraph {
/// Construct from FLANN matrix.
MatrixProxy (flann::Matrix<DATA_TYPE> const &m)
: rows(m.rows), cols(m.cols), stride(m.stride), data(m.data) {
BOOST_VERIFY(stride % A == 0);
if (stride % A) throw invalid_argument("bad alignment");
}
#endif
#ifdef __OPENCV_CORE_HPP__
/// Construct from OpenCV matrix.
MatrixProxy (cv::Mat const &m)
: rows(m.rows), cols(m.cols), stride(m.step), data(m.data) {
BOOST_VERIFY(stride % A == 0);
if (stride % A) throw invalid_argument("bad alignment");
}
#endif
#ifdef NPY_NDARRAYOBJECT_H
/// Construct from NumPy matrix.
MatrixProxy (PyArrayObject *obj) {
BOOST_VERIFY(obj->nd == 2);
if (!obj || (obj->nd != 2)) throw invalid_argument("bad array shape");
rows = obj->dimensions[0];
cols = obj->dimensions[1];
stride = obj->strides[0];
data = reinterpret_cast<uint8_t const *>(obj->data);
BOOST_VERIFY(obj->descr->elsize == sizeof(DATA_TYPE));
BOOST_VERIFY(stride % A == 0);
BOOST_VERIFY(stride >= cols * sizeof(DATA_TYPE));
if (obj->descr->elsize != sizeof(DATA_TYPE)) throw invalid_argument("bad data type size");
if (stride % A) throw invalid_argument("bad alignment");
if (!(stride >= cols * sizeof(DATA_TYPE))) throw invalid_argument("bad stride");
}
#endif
#endif
@@ -287,9 +286,9 @@ namespace kgraph {
if (K == 0) {
K = result.dim();
}
BOOST_VERIFY(gs.dim() >= K);
BOOST_VERIFY(result.dim() >= K);
BOOST_VERIFY(gs.size() >= result.size());
if (!(gs.dim() >= K)) throw invalid_argument("gs.dim() >= K");
if (!(result.dim() >= K)) throw invalid_argument("result.dim() >= K");
if (!(gs.size() >= result.size())) throw invalid_argument("gs.size() > result.size()");
float sum = 0;
for (unsigned i = 0; i < result.size(); ++i) {
float const *gs_row = gs[i];
View
@@ -284,7 +284,7 @@ namespace kgraph {
virtual ~KGraphImpl () {
}
virtual void load (char const *path) {
BOOST_VERIFY(sizeof(unsigned) == sizeof(uint32_t));
static_assert(sizeof(unsigned) == sizeof(uint32_t), "unsigned must be 32-bit");
ifstream is(path, ios::binary);
char magic[KGRAPH_MAGIC_SIZE];
uint32_t sig_version;
@@ -439,8 +439,8 @@ namespace kgraph {
}
}
else { // user-provided starting points.
BOOST_VERIFY(ids);
BOOST_VERIFY(L < params.K);
if (!ids) throw invalid_argument("no initial data provided via ids");
if (!(L < params.K)) throw invalid_argument("L < params.K");
for (unsigned l = 0; l < L; ++l) {
knn[l].id = ids[l];
}
@@ -519,10 +519,12 @@ namespace kgraph {
}
}
unsigned L = results.size();
/*
if (!(L <= params.K)) {
cerr << L << ' ' << params.K << endl;
}
BOOST_VERIFY(L <= params.K);
*/
if (!(L <= params.K)) throw runtime_error("L <= params.K");
// check epsilon
if (ids) {
for (unsigned k = 0; k < L; ++k) {
@@ -542,7 +544,7 @@ namespace kgraph {
}
virtual void get_nn (unsigned id, unsigned *nns, float *dist, unsigned *pM, unsigned *pL) const {
BOOST_VERIFY(id < graph.size());
if (!(id < graph.size())) throw invalid_argument("id too big");
auto const &v = graph[id];
*pM = M[id];
*pL = v.size();
View
@@ -8,6 +8,8 @@
#ifndef WDONG_KGRAPH
#define WDONG_KGRAPH
#include <stdexcept>
namespace kgraph {
static unsigned const default_iterations = 30;
static unsigned const default_L = 100;
@@ -280,6 +282,22 @@ namespace kgraph {
return VectorSearchOracle(data, q, dist);
}
};
class invalid_argument: public std::invalid_argument {
public:
using std::invalid_argument::invalid_argument;
};
class runtime_error: public std::runtime_error {
public:
using std::runtime_error::runtime_error;
};
class io_error: public runtime_error {
public:
using runtime_error::runtime_error;
};
}
#endif
View
@@ -55,19 +55,18 @@ namespace {
std::ifstream is(path.c_str(), std::ios::binary);
unsigned header[LSHKIT_HEADER]; /* entry size, row, col */
is.read((char *)header, sizeof header);
BOOST_VERIFY(is);
if (!is) throw kgraph::io_error(path);
unsigned elsize = header[0];
unsigned N = header[1];
unsigned D = header[2];
npy_intp dims[2] = {N, D};
PyArray_Descr *descr = PyArray_DescrFromTypeObject(type);
BOOST_VERIFY(descr->elsize == elsize);
if (!(descr->elsize == elsize)) throw kgraph::io_error(path);
PyObject *nd = PyArray_SimpleNewFromDescr(2, &dims[0], descr);
BOOST_VERIFY(nd);
BOOST_VERIFY(PyArray_ITEMSIZE(nd) == elsize);
if ((!nd) || (PyArray_ITEMSIZE(nd) != elsize)) throw kgraph::runtime_error("error creating numpy matrix");
float *buf = reinterpret_cast<float*>(PyArray_DATA(nd));
is.read((char *)&buf[0], 1LL * N * D * elsize);
BOOST_VERIFY(is);
if (!is) throw kgraph::io_error(path);
return nd;
}
@@ -228,15 +227,23 @@ namespace {
};
void check_array (PyArrayObject *array, float) {
BOOST_VERIFY(array->nd == 2);
BOOST_VERIFY(array->dimensions[1] % 4 == 0);
BOOST_VERIFY(array->descr->type_num == NPY_FLOAT);
do {
if (array->nd != 2) break;
if (array->dimensions[1] % 4) break;
if (array->descr->type_num != NPY_FLOAT) break;
return;
} while (false);
throw kgraph::invalid_argument("bad array type");
}
void check_array (PyArrayObject *array, double) {
BOOST_VERIFY(array->nd == 2);
BOOST_VERIFY(array->dimensions[1] % 4 == 0);
BOOST_VERIFY(array->descr->type_num == NPY_DOUBLE);
do {
if (array->nd != 2) break;
if (array->dimensions[1] % 4) break;
if (array->descr->type_num != NPY_DOUBLE) break;
return;
} while (false);
throw kgraph::invalid_argument("bad array type");
}
class ImplBase {
@@ -357,12 +364,12 @@ class KGraph {
cerr << " index.build(...)" << endl;
cerr << " index.search(query, ...)" << endl;
cerr << "!!!!!!!!!!" << endl;
BOOST_VERIFY(0);
throw kgraph::invalid_argument("obsolete constructor");
}
KGraph (PyObject *data, string const &metric): impl(nullptr) {
PyArrayObject *pd = reinterpret_cast<PyArrayObject *>(data);
BOOST_VERIFY(pd);
if (!pd) throw kgraph::invalid_argument("bad array");
if (metric == "euclidean") {
switch (pd->descr->type_num) {
case NPY_FLOAT: impl = new Impl<float, EuclideanLike>(pd); break;

0 comments on commit e8cbdbd

Please sign in to comment.