Skip to content

Commit

Permalink
v1.7.4 add C API functions for ngtd
Browse files Browse the repository at this point in the history
  • Loading branch information
masajiro committed May 22, 2019
1 parent 9bf9f5d commit d5d4dd9
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 17 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.7.3
1.7.4
2 changes: 2 additions & 0 deletions bin/ngt/ngt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ main(int argc, char **argv)
ngt.prune(args);
} else if (command == "reconstruct-graph") {
ngt.reconstructGraph(args);
} else if (command == "eval") {
NGT::Optimizer::evaluate(args);
#ifndef NGT_SHARED_MEMORY_ALLOCATOR
} else if (command == "extract-query") {
NGT::Optimizer::extractQueries(args);
Expand Down
121 changes: 106 additions & 15 deletions lib/NGT/Capi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,57 @@ NGTObjectDistances ngt_create_empty_results(NGTError error) {
}
}

static bool ngt_search_index_(NGT::Index* pindex, NGT::Object *ngtquery, size_t size, float epsilon, float radius, NGTObjectDistances results) {
// set search prameters.
NGT::SearchContainer sc(*ngtquery); // search parametera container.

sc.setResults(static_cast<NGT::ObjectDistances*>(results)); // set the result set.
sc.setSize(size); // the number of resultant objects.
sc.setRadius(radius); // search radius.
sc.setEpsilon(epsilon); // set exploration coefficient.

pindex->search(sc);

// delete the query object.
pindex->deleteObject(ngtquery);
return true;
}

bool ngt_search_index(NGTIndex index, double *query, int32_t query_dim, size_t size, float epsilon, float radius, NGTObjectDistances results, NGTError error) {
if(index == NULL || query == NULL || results == NULL){
if(index == NULL || query == NULL || results == NULL || query_dim <= 0){
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : parametor error: index = " << index << " query = " << query << " results = " << results << " query_dim = " << query_dim;
operate_error_string_(ss, error);
return false;
}

NGT::Index* pindex = static_cast<NGT::Index*>(index);
NGT::Object *ngtquery = NULL;

if(radius < 0.0){
radius = FLT_MAX;
}

try{
std::vector<double> vquery(&query[0], &query[query_dim]);
ngtquery = pindex->allocateObject(vquery);
ngt_search_index_(pindex, ngtquery, size, epsilon, radius, results);
}catch(std::exception &err) {
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : Error: " << err.what();
operate_error_string_(ss, error);
if(ngtquery != NULL){
pindex->deleteObject(ngtquery);
}
return false;
}
return true;
}

bool ngt_search_index_as_float(NGTIndex index, float *query, int32_t query_dim, size_t size, float epsilon, float radius, NGTObjectDistances results, NGTError error) {
if(index == NULL || query == NULL || results == NULL || query_dim <= 0){
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : parametor error: index = " << index << " query = " << query << " results = " << results;
ss << "Capi : " << __FUNCTION__ << "() : parametor error: index = " << index << " query = " << query << " results = " << results << " query_dim = " << query_dim;
operate_error_string_(ss, error);
return false;
}
Expand All @@ -281,20 +328,9 @@ bool ngt_search_index(NGTIndex index, double *query, int32_t query_dim, size_t s
}

try{
std::vector<double> vquery(&query[0], &query[query_dim]);
std::vector<float> vquery(&query[0], &query[query_dim]);
ngtquery = pindex->allocateObject(vquery);
// set search prameters.
NGT::SearchContainer sc(*ngtquery); // search parametera container.

sc.setResults(static_cast<NGT::ObjectDistances*>(results)); // set the result set.
sc.setSize(size); // the number of resultant objects.
sc.setRadius(radius); // search radius.
sc.setEpsilon(epsilon); // set exploration coefficient.

pindex->search(sc);

// delete the query object.
pindex->deleteObject(ngtquery);
ngt_search_index_(pindex, ngtquery, size, epsilon, radius, results);
}catch(std::exception &err) {
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : Error: " << err.what();
Expand All @@ -307,6 +343,7 @@ bool ngt_search_index(NGTIndex index, double *query, int32_t query_dim, size_t s
return true;
}


// * deprecated *
int32_t ngt_get_size(NGTObjectDistances results, NGTError error) {
if(results == NULL){
Expand Down Expand Up @@ -346,6 +383,13 @@ NGTObjectDistance ngt_get_result(const NGTObjectDistances results, const uint32_
}

ObjectID ngt_insert_index(NGTIndex index, double *obj, uint32_t obj_dim, NGTError error) {
if(index == NULL || obj == NULL || obj_dim == 0){
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : parametor error: index = " << index << " obj = " << obj << " obj_dim = " << obj_dim;
operate_error_string_(ss, error);
return 0;
}

try{
NGT::Index* pindex = static_cast<NGT::Index*>(index);
std::vector<double> vobj(&obj[0], &obj[obj_dim]);
Expand All @@ -359,6 +403,13 @@ ObjectID ngt_insert_index(NGTIndex index, double *obj, uint32_t obj_dim, NGTErro
}

ObjectID ngt_append_index(NGTIndex index, double *obj, uint32_t obj_dim, NGTError error) {
if(index == NULL || obj == NULL || obj_dim == 0){
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : parametor error: index = " << index << " obj = " << obj << " obj_dim = " << obj_dim;
operate_error_string_(ss, error);
return 0;
}

try{
NGT::Index* pindex = static_cast<NGT::Index*>(index);
std::vector<double> vobj(&obj[0], &obj[obj_dim]);
Expand All @@ -371,6 +422,46 @@ ObjectID ngt_append_index(NGTIndex index, double *obj, uint32_t obj_dim, NGTErro
}
}

ObjectID ngt_insert_index_as_float(NGTIndex index, float *obj, uint32_t obj_dim, NGTError error) {
if(index == NULL || obj == NULL || obj_dim == 0){
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : parametor error: index = " << index << " obj = " << obj << " obj_dim = " << obj_dim;
operate_error_string_(ss, error);
return 0;
}

try{
NGT::Index* pindex = static_cast<NGT::Index*>(index);
std::vector<float> vobj(&obj[0], &obj[obj_dim]);
return pindex->insert(vobj);
}catch(std::exception &err) {
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : Error: " << err.what();
operate_error_string_(ss, error);
return 0;
}
}

ObjectID ngt_append_index_as_float(NGTIndex index, float *obj, uint32_t obj_dim, NGTError error) {
if(index == NULL || obj == NULL || obj_dim == 0){
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : parametor error: index = " << index << " obj = " << obj << " obj_dim = " << obj_dim;
operate_error_string_(ss, error);
return 0;
}

try{
NGT::Index* pindex = static_cast<NGT::Index*>(index);
std::vector<float> vobj(&obj[0], &obj[obj_dim]);
return pindex->append(vobj);
}catch(std::exception &err) {
std::stringstream ss;
ss << "Capi : " << __FUNCTION__ << "() : Error: " << err.what();
operate_error_string_(ss, error);
return 0;
}
}

bool ngt_batch_append_index(NGTIndex index, float *obj, uint32_t data_count, NGTError error) {
try{
NGT::Index* pindex = static_cast<NGT::Index*>(index);
Expand Down
6 changes: 6 additions & 0 deletions lib/NGT/Capi.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ bool ngt_set_property_distance_type_cosine(NGTProperty, NGTError);
NGTObjectDistances ngt_create_empty_results(NGTError);

bool ngt_search_index(NGTIndex, double*, int32_t, size_t, float, float, NGTObjectDistances, NGTError);

bool ngt_search_index_as_float(NGTIndex, float*, int32_t, size_t, float, float, NGTObjectDistances, NGTError);

int32_t ngt_get_size(NGTObjectDistances, NGTError); // deprecated

Expand All @@ -88,6 +90,10 @@ ObjectID ngt_insert_index(NGTIndex, double*, uint32_t, NGTError);

ObjectID ngt_append_index(NGTIndex, double*, uint32_t, NGTError);

ObjectID ngt_insert_index_as_float(NGTIndex, float*, uint32_t, NGTError);

ObjectID ngt_append_index_as_float(NGTIndex, float*, uint32_t, NGTError);

bool ngt_batch_append_index(NGTIndex, float*, uint32_t, NGTError);

bool ngt_create_index(NGTIndex, uint32_t, NGTError);
Expand Down
1 change: 0 additions & 1 deletion lib/NGT/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,4 +840,3 @@
}
}


77 changes: 77 additions & 0 deletions lib/NGT/Optimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,83 @@ namespace NGT {
return 0;
}

static void evaluate(Args &args)
{
const string usage = "Usage: ngt eval [-n number-of-results] [-m mode(r=recall)] [-g ground-truth-size] [-o output-mode] ground-truth search-result\n"
" Make a ground truth list (linear search): \n"
" ngt search -i s -n 20 -o e index query.list > ground-truth.list";

string gtFile, resultFile;
try {
gtFile = args.get("#1");
} catch (...) {
cerr << "ground truth is not specified." << endl;
cerr << usage << endl;
return;
}
try {
resultFile = args.get("#2");
} catch (...) {
cerr << "result file is not specified." << endl;
cerr << usage << endl;
return;
}

size_t resultSize = args.getl("n", 0);
if (resultSize != 0) {
cerr << "The specified number of results=" << resultSize << endl;
}

size_t groundTruthSize = args.getl("g", 0);

bool recall = false;
if (args.getChar("m", '-') == 'r') {
cerr << "Recall" << endl;
recall = true;
}
char omode = args.getChar("o", '-');

ifstream resultStream(resultFile);
if (!resultStream) {
cerr << "Cannot open the specified target file. " << resultFile << endl;
cerr << usage << endl;
return;
}

ifstream gtStream(gtFile);
if (!gtStream) {
cerr << "Cannot open the specified GT file. " << gtFile << endl;
cerr << usage << endl;
return;
}

vector<Accuracy> accuracies;
string type;
size_t actualResultSize = 0;
evaluate(gtStream, resultStream, accuracies, type, actualResultSize, resultSize, groundTruthSize, recall);

cout << "# # of evaluated resultant objects per query=" << actualResultSize << endl;
if (recall) {
cout << "# " << type << "\t# of Queries\tRecall\t";
} else {
cout << "# " << type << "\t# of Queries\tPrecision\t";
}
if (omode == 'd') {
cout << "# of computations\t# of visted nodes" << endl;
for (auto it = accuracies.begin(); it != accuracies.end(); ++it) {
cout << (*it).keyValue << "\t" << (*it).totalCount << "\t" << (*it).averageAccuracy << "\t"
<< (*it).averageDistanceCount << "\t" << (*it).averageVisitCount << endl;
}
} else {
cout << "Time(msec)\t# of computations\t# of visted nodes" << endl;
for (auto it = accuracies.begin(); it != accuracies.end(); ++it) {
cout << (*it).keyValue << "\t" << (*it).totalCount << "\t" << (*it).averageAccuracy << "\t" << (*it).averageTime << "\t"
<< (*it).averageDistanceCount << "\t" << (*it).averageVisitCount << endl;
}
}

}

};

}; // NGT
Expand Down

0 comments on commit d5d4dd9

Please sign in to comment.