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

C++ Example #167

Closed
ashfaq92 opened this issue Nov 13, 2019 · 4 comments
Closed

C++ Example #167

ashfaq92 opened this issue Nov 13, 2019 · 4 comments
Assignees

Comments

@ashfaq92
Copy link
Contributor

ashfaq92 commented Nov 13, 2019

Hi!
In your "readme.md" and "examples" folder, examples are provided only with python bindings.
In https://github.com/jlmelville/rcpphnsw rough equivalent of the serialization/deserialization example from this hnswlib README file is provided in 'R' language.
But nowhere C++ example of serialization/deserialization equivalent to current README example is provided. I want to use hnswlib in my c++ project. I was wondering how to do the exact functionality in c++. It would be great if you translate examples given in python to c++.
Thank you!

@yurymalkov
Copy link
Member

@ashfaq92

Thanks for noticing! I'll make an example.

@yurymalkov yurymalkov self-assigned this Nov 14, 2019
@jlmelville
Copy link
Contributor

jlmelville commented Nov 14, 2019

The basics of creating/re-sizing/re-loading an index, as used in RcppHNSW are below. It doesn't really do anything, but it should compile and run without causing your computer to explode, which is 90% of the battle in C++. Hopefully you can work out the rest!

#include <memory>
#include "hnswlib.h"
void example()
  auto dim = 16;
  auto num_elements = 100000;
  auto init_num_elements = num_elements / 2;
  auto M = 16;
  auto ef_construction = 200;

  using dist_t = float;
  using Distance = hnswlib::L2Space;

  // create the index
  auto space = std::unique_ptr<Distance>(new Distance(dim));
  auto appr_alg = std::unique_ptr<hnswlib::HierarchicalNSW<dist_t>>(
    new hnswlib::HierarchicalNSW<dist_t>(space.get(), init_num_elements, M,
                                         ef_construction));

  // resize it
  appr_alg->resizeIndex(num_elements);

  // or save and reload it
  std::string path_to_index = "myindex.hnsw";
  appr_alg->saveIndex(path_to_index);
  appr_alg.reset(new hnswlib::HierarchicalNSW<dist_t>(space.get(), path_to_index));
}

@ashfaq92
Copy link
Contributor Author

@jlmelville thanks for prompt response. Sorry for late reply due to "timezones :(". I have run your code and it works without error (as you said :). But it would be really nice if you update this code according to the readme file. I mean if it make HNSW graph with random numbers and finds nearest neighbor for any random query point. Then we may add this code in readme files so that future c++ beginners may embed that in their code (like me).

@Akshaysharma29
Copy link

Akshaysharma29 commented Mar 4, 2020

With the addition to the above code starter code. In this code querying the embedding is added(with query result).
`auto dim = 512;
auto num_elements = 100000;
auto init_num_elements = num_elements / 2;
auto M = 16;
auto ef_construction = 200;

using dist_t = float;
using Distance = hnswlib::L2Space;

// create the index
auto space = std::unique_ptr<Distance>(new Distance(dim));
auto appr_alg = std::unique_ptr<hnswlib::HierarchicalNSW<dist_t>>(
        new hnswlib::HierarchicalNSW<dist_t>(space.get(), init_num_elements, M,
                                             ef_construction));

typedef size_t labeltype;
appr_alg->setEf(200);
auto ret=appr_alg->searchKnn(default_emb,1);//'1' is the nearest neg

std::vector<std::pair<dist_t, labeltype>> result;//result return after knn search


int f=0;
int id_label;
float mn=100000;
if(ret.size()==0)
{
    counter_value+=1;
    appr_alg->addPoint(default_emb,counter_value);
    LOGD("This is empty ret");
} else{
    LOGD("Non empty ret");
    while (!ret.empty()) {
        result.push_back(ret.top());
        ret.pop();
    }
    for(int i =0;i<result.size();i++)
    {
        LOGD("hnswlib result:(1)distance:) %f => (2)label:) %d",result[i].first,result[i].second);
        if(result[i].first<(0.5)&&mn>result[i].first)
        {
            f=1;
            mn=result[i].first;
            id_label=result[i].second;
        }
    }
    if(f==0){
        counter_value+=1;
        id_label=counter_value;
        appr_alg->addPoint(default_emb,counter_value);
        LOGD("New entry generated");
    }else{
        LOGD("Id we get:%d",id_label);
    }
}

result.clear();`

@ashfaq92 ashfaq92 closed this as completed Mar 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants