Skip to content

Commit 47a7269

Browse files
committed
/n
1 parent 23e720c commit 47a7269

File tree

6 files changed

+62
-32
lines changed

6 files changed

+62
-32
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
*.exe
22
*.in
33
*.out
4-
*.o
4+
*.o
5+
*.exp
6+
*.lib

CPU/vector_initialize.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <vector>
55
#include <cmath>
6-
#include <omp.h>
6+
#include "omp.h"
77

88
struct Item {
99
Item(std::vector<double> _values) : values(_values) {}
@@ -54,7 +54,6 @@ struct Item {
5454

5555
double cosine_similarity_with_normalisation(Item& other) {
5656
double dot_product = 0.0;
57-
// #pragma omp parallel for reduction(+:dot_product)
5857
for (size_t i = 0; i < values.size(); ++i) {
5958
dot_product += values[i] * other.values[i];
6059
}

compile.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
g++ -c -fopenmp main.cpp -o main.o
22
g++ -c -fopenmp hnsw_implementation/hnsw.cpp -o hnsw.o
3-
g++ main.o hnsw.o -o my_program
3+
g++ -fopenmp main.o hnsw.o -o my_program
4+
nvcc GPU/ann.cu -o nn -O3 -arch=sm_60

hnsw_implementation/hnsw.cpp

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,37 @@
1010
#include <omp.h>
1111
using namespace std;
1212

13-
vector<int> HNSWGraph::searchLayer(Item& q, int ep, int ef, int lc) {
13+
vector<int> HNSWGraph::searchLayer(Item& q, int entry_point, int ef, int lc) {
1414
set<pair<double, int>> candidates;
1515
set<pair<double, int>> nearestNeighbors;
1616
unordered_set<int> isVisited;
1717

18-
double td = q.dist(items[ep]);
19-
candidates.insert(make_pair(td, ep));
20-
nearestNeighbors.insert(make_pair(td, ep));
21-
isVisited.insert(ep);
18+
double td = q.dist(items[entry_point]);
19+
candidates.insert(make_pair(td, entry_point));
20+
nearestNeighbors.insert(make_pair(td, entry_point));
21+
isVisited.insert(entry_point);
2222
while (!candidates.empty()) {
23-
auto ci = candidates.begin(); candidates.erase(candidates.begin());
23+
auto ci = candidates.begin();
24+
candidates.erase(candidates.begin());
2425
int nid = ci->second;
2526
auto fi = nearestNeighbors.end(); fi--;
26-
if (ci->first > fi->first) break;
27+
if (ci->first > fi->first) {
28+
break;
29+
}
2730
for (int ed: layerEdgeLists[lc][nid]) {
28-
if (isVisited.find(ed) != isVisited.end()) continue;
29-
fi = nearestNeighbors.end(); fi--;
31+
if (isVisited.find(ed) != isVisited.end()) {
32+
continue;
33+
}
34+
fi = nearestNeighbors.end();
35+
fi--;
3036
isVisited.insert(ed);
3137
td = q.dist(items[ed]);
3238
if ((td < fi->first) || nearestNeighbors.size() < ef) {
3339
candidates.insert(make_pair(td, ed));
3440
nearestNeighbors.insert(make_pair(td, ed));
35-
if (nearestNeighbors.size() > ef) nearestNeighbors.erase(fi);
41+
if (nearestNeighbors.size() > ef) {
42+
nearestNeighbors.erase(fi);
43+
}
3644
}
3745
}
3846
}
@@ -43,50 +51,65 @@ vector<int> HNSWGraph::searchLayer(Item& q, int ep, int ef, int lc) {
4351

4452
vector<int> HNSWGraph::KNNSearch(Item& q, int K) {
4553
int maxLyer = layerEdgeLists.size() - 1;
46-
int ep = enterNode;
47-
for (int l = maxLyer; l >= 1; l--) ep = searchLayer(q, ep, 1, l)[0];
48-
return searchLayer(q, ep, K, 0);
54+
int entry_point = enterNode;
55+
for (int l = maxLyer; l >= 1; l--) {
56+
entry_point = searchLayer(q, entry_point, 1, l)[0];
57+
}
58+
return searchLayer(q, entry_point, K, 0);
4959
}
5060

5161
void HNSWGraph::addEdge(int st, int ed, int lc) {
52-
if (st == ed) return;
62+
if (st == ed) {
63+
return;
64+
}
5365
layerEdgeLists[lc][st].push_back(ed);
5466
layerEdgeLists[lc][ed].push_back(st);
5567
}
5668

5769
void HNSWGraph::Insert(Item& q) {
5870
int nid = items.size();
5971
itemNum++; items.push_back(q);
60-
// sample layer
6172
int maxLyer = layerEdgeLists.size() - 1;
6273
int l = 0;
6374
uniform_real_distribution<double> distribution(0.0,1.0);
6475
while(l < ml && (1.0 / ml <= distribution(generator))) {
6576
l++;
66-
if (layerEdgeLists.size() <= l) layerEdgeLists.push_back(unordered_map<int, vector<int>>());
77+
if (layerEdgeLists.size() <= l) {
78+
layerEdgeLists.push_back(unordered_map<int, vector<int>>());
79+
}
6780
}
6881
if (nid == 0) {
6982
enterNode = nid;
7083
return;
7184
}
72-
// search up layer entrance
73-
int ep = enterNode;
74-
for (int i = maxLyer; i > l; i--) ep = searchLayer(q, ep, 1, i)[0];
85+
int entry_point = enterNode;
86+
for (int i = maxLyer; i > l; i--) {
87+
entry_point = searchLayer(q, entry_point, 1, i)[0];
88+
}
89+
#pragma omp parallel for
7590
for (int i = min(l, maxLyer); i >= 0; i--) {
7691
int MM = l == 0 ? MMax0 : MMax;
77-
vector<int> neighbors = searchLayer(q, ep, efConstruction, i);
92+
vector<int> neighbors = searchLayer(q, entry_point, efConstruction, i);
7893
vector<int> selectedNeighbors = vector<int>(neighbors.begin(), neighbors.begin()+min(int(neighbors.size()), M));
79-
for (int n: selectedNeighbors) addEdge(n, nid, i);
94+
for (int n: selectedNeighbors) {
95+
addEdge(n, nid, i);
96+
}
8097
for (int n: selectedNeighbors) {
8198
if (layerEdgeLists[i][n].size() > MM) {
8299
vector<pair<double, int>> distPairs;
83-
for (int nn: layerEdgeLists[i][n]) distPairs.emplace_back(items[n].dist(items[nn]), nn);
100+
for (int nn: layerEdgeLists[i][n]) {
101+
distPairs.emplace_back(items[n].dist(items[nn]), nn);
102+
}
84103
sort(distPairs.begin(), distPairs.end());
85104
layerEdgeLists[i][n].clear();
86-
for (int d = 0; d < min(int(distPairs.size()), MM); d++) layerEdgeLists[i][n].push_back(distPairs[d].second);
105+
for (int d = 0; d < min(int(distPairs.size()), MM); d++) {
106+
layerEdgeLists[i][n].push_back(distPairs[d].second);
107+
}
87108
}
88109
}
89-
ep = selectedNeighbors[0];
110+
entry_point = selectedNeighbors[0];
111+
}
112+
if (l == layerEdgeLists.size() - 1) {
113+
enterNode = nid;
90114
}
91-
if (l == layerEdgeLists.size() - 1) enterNode = nid;
92115
}

hnsw_implementation/hnsw.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <vector>
66
#include <unordered_map>
77
#include <iostream>
8-
#include <omp.h>
98

109
#include "../CPU/vector_initialize.h"
1110
using namespace std;

main.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <memory>
99
#include <string>
1010
#include <sstream>
11-
#include <omp.h>
1211
using namespace std;
1312

1413
void readInputFromFile(const string& filename, int& D, int& N, int& M, vector<Item>& base, vector<Item>& queries) {
@@ -129,8 +128,15 @@ int main(int argc, char* argv[]) {
129128
outfile << endl;
130129
total_hnsw_time += double(clock() - begin_time) / CLOCKS_PER_SEC;
131130

132-
if (knns[0] == distPairs[0].second) numHits++;
131+
if (knns[0] == distPairs[0].second) {
132+
numHits++;
133+
}
133134
}
135+
136+
137+
// myHNSWGraph.printGraph(); //Uncomment to visualize graph layers
138+
139+
134140
for (Item& item : base) {
135141
item.normalize();
136142
}

0 commit comments

Comments
 (0)