umappp 0.1.6 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,279 +3,322 @@
3
3
 
4
4
  namespace hnswlib {
5
5
 
6
- static float
7
- L2Sqr(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
8
- float *pVect1 = (float *) pVect1v;
9
- float *pVect2 = (float *) pVect2v;
10
- size_t qty = *((size_t *) qty_ptr);
11
-
12
- float res = 0;
13
- for (size_t i = 0; i < qty; i++) {
14
- float t = *pVect1 - *pVect2;
15
- pVect1++;
16
- pVect2++;
17
- res += t * t;
18
- }
19
- return (res);
6
+ static float
7
+ L2Sqr(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
8
+ float *pVect1 = (float *) pVect1v;
9
+ float *pVect2 = (float *) pVect2v;
10
+ size_t qty = *((size_t *) qty_ptr);
11
+
12
+ float res = 0;
13
+ for (size_t i = 0; i < qty; i++) {
14
+ float t = *pVect1 - *pVect2;
15
+ pVect1++;
16
+ pVect2++;
17
+ res += t * t;
18
+ }
19
+ return (res);
20
+ }
21
+
22
+ #if defined(USE_AVX512)
23
+
24
+ // Favor using AVX512 if available.
25
+ static float
26
+ L2SqrSIMD16ExtAVX512(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
27
+ float *pVect1 = (float *) pVect1v;
28
+ float *pVect2 = (float *) pVect2v;
29
+ size_t qty = *((size_t *) qty_ptr);
30
+ float PORTABLE_ALIGN64 TmpRes[16];
31
+ size_t qty16 = qty >> 4;
32
+
33
+ const float *pEnd1 = pVect1 + (qty16 << 4);
34
+
35
+ __m512 diff, v1, v2;
36
+ __m512 sum = _mm512_set1_ps(0);
37
+
38
+ while (pVect1 < pEnd1) {
39
+ v1 = _mm512_loadu_ps(pVect1);
40
+ pVect1 += 16;
41
+ v2 = _mm512_loadu_ps(pVect2);
42
+ pVect2 += 16;
43
+ diff = _mm512_sub_ps(v1, v2);
44
+ // sum = _mm512_fmadd_ps(diff, diff, sum);
45
+ sum = _mm512_add_ps(sum, _mm512_mul_ps(diff, diff));
20
46
  }
21
47
 
22
- #if defined(USE_AVX)
48
+ _mm512_store_ps(TmpRes, sum);
49
+ float res = TmpRes[0] + TmpRes[1] + TmpRes[2] + TmpRes[3] + TmpRes[4] + TmpRes[5] + TmpRes[6] +
50
+ TmpRes[7] + TmpRes[8] + TmpRes[9] + TmpRes[10] + TmpRes[11] + TmpRes[12] +
51
+ TmpRes[13] + TmpRes[14] + TmpRes[15];
23
52
 
24
- // Favor using AVX if available.
25
- static float
26
- L2SqrSIMD16Ext(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
27
- float *pVect1 = (float *) pVect1v;
28
- float *pVect2 = (float *) pVect2v;
29
- size_t qty = *((size_t *) qty_ptr);
30
- float PORTABLE_ALIGN32 TmpRes[8];
31
- size_t qty16 = qty >> 4;
32
-
33
- const float *pEnd1 = pVect1 + (qty16 << 4);
34
-
35
- __m256 diff, v1, v2;
36
- __m256 sum = _mm256_set1_ps(0);
37
-
38
- while (pVect1 < pEnd1) {
39
- v1 = _mm256_loadu_ps(pVect1);
40
- pVect1 += 8;
41
- v2 = _mm256_loadu_ps(pVect2);
42
- pVect2 += 8;
43
- diff = _mm256_sub_ps(v1, v2);
44
- sum = _mm256_add_ps(sum, _mm256_mul_ps(diff, diff));
45
-
46
- v1 = _mm256_loadu_ps(pVect1);
47
- pVect1 += 8;
48
- v2 = _mm256_loadu_ps(pVect2);
49
- pVect2 += 8;
50
- diff = _mm256_sub_ps(v1, v2);
51
- sum = _mm256_add_ps(sum, _mm256_mul_ps(diff, diff));
52
- }
53
+ return (res);
54
+ }
55
+ #endif
53
56
 
54
- _mm256_store_ps(TmpRes, sum);
55
- return TmpRes[0] + TmpRes[1] + TmpRes[2] + TmpRes[3] + TmpRes[4] + TmpRes[5] + TmpRes[6] + TmpRes[7];
57
+ #if defined(USE_AVX)
58
+
59
+ // Favor using AVX if available.
60
+ static float
61
+ L2SqrSIMD16ExtAVX(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
62
+ float *pVect1 = (float *) pVect1v;
63
+ float *pVect2 = (float *) pVect2v;
64
+ size_t qty = *((size_t *) qty_ptr);
65
+ float PORTABLE_ALIGN32 TmpRes[8];
66
+ size_t qty16 = qty >> 4;
67
+
68
+ const float *pEnd1 = pVect1 + (qty16 << 4);
69
+
70
+ __m256 diff, v1, v2;
71
+ __m256 sum = _mm256_set1_ps(0);
72
+
73
+ while (pVect1 < pEnd1) {
74
+ v1 = _mm256_loadu_ps(pVect1);
75
+ pVect1 += 8;
76
+ v2 = _mm256_loadu_ps(pVect2);
77
+ pVect2 += 8;
78
+ diff = _mm256_sub_ps(v1, v2);
79
+ sum = _mm256_add_ps(sum, _mm256_mul_ps(diff, diff));
80
+
81
+ v1 = _mm256_loadu_ps(pVect1);
82
+ pVect1 += 8;
83
+ v2 = _mm256_loadu_ps(pVect2);
84
+ pVect2 += 8;
85
+ diff = _mm256_sub_ps(v1, v2);
86
+ sum = _mm256_add_ps(sum, _mm256_mul_ps(diff, diff));
56
87
  }
57
88
 
58
- #elif defined(USE_SSE)
59
-
60
- static float
61
- L2SqrSIMD16Ext(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
62
- float *pVect1 = (float *) pVect1v;
63
- float *pVect2 = (float *) pVect2v;
64
- size_t qty = *((size_t *) qty_ptr);
65
- float PORTABLE_ALIGN32 TmpRes[8];
66
- size_t qty16 = qty >> 4;
67
-
68
- const float *pEnd1 = pVect1 + (qty16 << 4);
69
-
70
- __m128 diff, v1, v2;
71
- __m128 sum = _mm_set1_ps(0);
72
-
73
- while (pVect1 < pEnd1) {
74
- //_mm_prefetch((char*)(pVect2 + 16), _MM_HINT_T0);
75
- v1 = _mm_loadu_ps(pVect1);
76
- pVect1 += 4;
77
- v2 = _mm_loadu_ps(pVect2);
78
- pVect2 += 4;
79
- diff = _mm_sub_ps(v1, v2);
80
- sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
81
-
82
- v1 = _mm_loadu_ps(pVect1);
83
- pVect1 += 4;
84
- v2 = _mm_loadu_ps(pVect2);
85
- pVect2 += 4;
86
- diff = _mm_sub_ps(v1, v2);
87
- sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
88
-
89
- v1 = _mm_loadu_ps(pVect1);
90
- pVect1 += 4;
91
- v2 = _mm_loadu_ps(pVect2);
92
- pVect2 += 4;
93
- diff = _mm_sub_ps(v1, v2);
94
- sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
95
-
96
- v1 = _mm_loadu_ps(pVect1);
97
- pVect1 += 4;
98
- v2 = _mm_loadu_ps(pVect2);
99
- pVect2 += 4;
100
- diff = _mm_sub_ps(v1, v2);
101
- sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
102
- }
89
+ _mm256_store_ps(TmpRes, sum);
90
+ return TmpRes[0] + TmpRes[1] + TmpRes[2] + TmpRes[3] + TmpRes[4] + TmpRes[5] + TmpRes[6] + TmpRes[7];
91
+ }
103
92
 
104
- _mm_store_ps(TmpRes, sum);
105
- return TmpRes[0] + TmpRes[1] + TmpRes[2] + TmpRes[3];
106
- }
107
93
  #endif
108
94
 
109
- #if defined(USE_SSE) || defined(USE_AVX)
110
- static float
111
- L2SqrSIMD16ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
112
- size_t qty = *((size_t *) qty_ptr);
113
- size_t qty16 = qty >> 4 << 4;
114
- float res = L2SqrSIMD16Ext(pVect1v, pVect2v, &qty16);
115
- float *pVect1 = (float *) pVect1v + qty16;
116
- float *pVect2 = (float *) pVect2v + qty16;
117
-
118
- size_t qty_left = qty - qty16;
119
- float res_tail = L2Sqr(pVect1, pVect2, &qty_left);
120
- return (res + res_tail);
95
+ #if defined(USE_SSE)
96
+
97
+ static float
98
+ L2SqrSIMD16ExtSSE(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
99
+ float *pVect1 = (float *) pVect1v;
100
+ float *pVect2 = (float *) pVect2v;
101
+ size_t qty = *((size_t *) qty_ptr);
102
+ float PORTABLE_ALIGN32 TmpRes[8];
103
+ size_t qty16 = qty >> 4;
104
+
105
+ const float *pEnd1 = pVect1 + (qty16 << 4);
106
+
107
+ __m128 diff, v1, v2;
108
+ __m128 sum = _mm_set1_ps(0);
109
+
110
+ while (pVect1 < pEnd1) {
111
+ //_mm_prefetch((char*)(pVect2 + 16), _MM_HINT_T0);
112
+ v1 = _mm_loadu_ps(pVect1);
113
+ pVect1 += 4;
114
+ v2 = _mm_loadu_ps(pVect2);
115
+ pVect2 += 4;
116
+ diff = _mm_sub_ps(v1, v2);
117
+ sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
118
+
119
+ v1 = _mm_loadu_ps(pVect1);
120
+ pVect1 += 4;
121
+ v2 = _mm_loadu_ps(pVect2);
122
+ pVect2 += 4;
123
+ diff = _mm_sub_ps(v1, v2);
124
+ sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
125
+
126
+ v1 = _mm_loadu_ps(pVect1);
127
+ pVect1 += 4;
128
+ v2 = _mm_loadu_ps(pVect2);
129
+ pVect2 += 4;
130
+ diff = _mm_sub_ps(v1, v2);
131
+ sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
132
+
133
+ v1 = _mm_loadu_ps(pVect1);
134
+ pVect1 += 4;
135
+ v2 = _mm_loadu_ps(pVect2);
136
+ pVect2 += 4;
137
+ diff = _mm_sub_ps(v1, v2);
138
+ sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
121
139
  }
122
- #endif
123
140
 
141
+ _mm_store_ps(TmpRes, sum);
142
+ return TmpRes[0] + TmpRes[1] + TmpRes[2] + TmpRes[3];
143
+ }
144
+ #endif
124
145
 
125
- #ifdef USE_SSE
126
- static float
127
- L2SqrSIMD4Ext(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
128
- float PORTABLE_ALIGN32 TmpRes[8];
129
- float *pVect1 = (float *) pVect1v;
130
- float *pVect2 = (float *) pVect2v;
131
- size_t qty = *((size_t *) qty_ptr);
146
+ #if defined(USE_SSE) || defined(USE_AVX) || defined(USE_AVX512)
147
+ static DISTFUNC<float> L2SqrSIMD16Ext = L2SqrSIMD16ExtSSE;
148
+
149
+ static float
150
+ L2SqrSIMD16ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
151
+ size_t qty = *((size_t *) qty_ptr);
152
+ size_t qty16 = qty >> 4 << 4;
153
+ float res = L2SqrSIMD16Ext(pVect1v, pVect2v, &qty16);
154
+ float *pVect1 = (float *) pVect1v + qty16;
155
+ float *pVect2 = (float *) pVect2v + qty16;
156
+
157
+ size_t qty_left = qty - qty16;
158
+ float res_tail = L2Sqr(pVect1, pVect2, &qty_left);
159
+ return (res + res_tail);
160
+ }
161
+ #endif
132
162
 
133
163
 
134
- size_t qty4 = qty >> 2;
164
+ #if defined(USE_SSE)
165
+ static float
166
+ L2SqrSIMD4Ext(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
167
+ float PORTABLE_ALIGN32 TmpRes[8];
168
+ float *pVect1 = (float *) pVect1v;
169
+ float *pVect2 = (float *) pVect2v;
170
+ size_t qty = *((size_t *) qty_ptr);
135
171
 
136
- const float *pEnd1 = pVect1 + (qty4 << 2);
137
172
 
138
- __m128 diff, v1, v2;
139
- __m128 sum = _mm_set1_ps(0);
173
+ size_t qty4 = qty >> 2;
140
174
 
141
- while (pVect1 < pEnd1) {
142
- v1 = _mm_loadu_ps(pVect1);
143
- pVect1 += 4;
144
- v2 = _mm_loadu_ps(pVect2);
145
- pVect2 += 4;
146
- diff = _mm_sub_ps(v1, v2);
147
- sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
148
- }
149
- _mm_store_ps(TmpRes, sum);
150
- return TmpRes[0] + TmpRes[1] + TmpRes[2] + TmpRes[3];
151
- }
175
+ const float *pEnd1 = pVect1 + (qty4 << 2);
152
176
 
153
- static float
154
- L2SqrSIMD4ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
155
- size_t qty = *((size_t *) qty_ptr);
156
- size_t qty4 = qty >> 2 << 2;
177
+ __m128 diff, v1, v2;
178
+ __m128 sum = _mm_set1_ps(0);
157
179
 
158
- float res = L2SqrSIMD4Ext(pVect1v, pVect2v, &qty4);
159
- size_t qty_left = qty - qty4;
160
-
161
- float *pVect1 = (float *) pVect1v + qty4;
162
- float *pVect2 = (float *) pVect2v + qty4;
163
- float res_tail = L2Sqr(pVect1, pVect2, &qty_left);
164
-
165
- return (res + res_tail);
180
+ while (pVect1 < pEnd1) {
181
+ v1 = _mm_loadu_ps(pVect1);
182
+ pVect1 += 4;
183
+ v2 = _mm_loadu_ps(pVect2);
184
+ pVect2 += 4;
185
+ diff = _mm_sub_ps(v1, v2);
186
+ sum = _mm_add_ps(sum, _mm_mul_ps(diff, diff));
166
187
  }
167
- #endif
188
+ _mm_store_ps(TmpRes, sum);
189
+ return TmpRes[0] + TmpRes[1] + TmpRes[2] + TmpRes[3];
190
+ }
168
191
 
169
- class L2Space : public SpaceInterface<float> {
170
-
171
- DISTFUNC<float> fstdistfunc_;
172
- size_t data_size_;
173
- size_t dim_;
174
- public:
175
- L2Space(size_t dim) {
176
- fstdistfunc_ = L2Sqr;
177
- #if defined(USE_SSE) || defined(USE_AVX)
178
- if (dim % 16 == 0)
179
- fstdistfunc_ = L2SqrSIMD16Ext;
180
- else if (dim % 4 == 0)
181
- fstdistfunc_ = L2SqrSIMD4Ext;
182
- else if (dim > 16)
183
- fstdistfunc_ = L2SqrSIMD16ExtResiduals;
184
- else if (dim > 4)
185
- fstdistfunc_ = L2SqrSIMD4ExtResiduals;
186
- #endif
187
- dim_ = dim;
188
- data_size_ = dim * sizeof(float);
189
- }
192
+ static float
193
+ L2SqrSIMD4ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) {
194
+ size_t qty = *((size_t *) qty_ptr);
195
+ size_t qty4 = qty >> 2 << 2;
190
196
 
191
- size_t get_data_size() {
192
- return data_size_;
193
- }
197
+ float res = L2SqrSIMD4Ext(pVect1v, pVect2v, &qty4);
198
+ size_t qty_left = qty - qty4;
194
199
 
195
- DISTFUNC<float> get_dist_func() {
196
- return fstdistfunc_;
197
- }
200
+ float *pVect1 = (float *) pVect1v + qty4;
201
+ float *pVect2 = (float *) pVect2v + qty4;
202
+ float res_tail = L2Sqr(pVect1, pVect2, &qty_left);
198
203
 
199
- void *get_dist_func_param() {
200
- return &dim_;
201
- }
204
+ return (res + res_tail);
205
+ }
206
+ #endif
202
207
 
203
- ~L2Space() {}
204
- };
205
-
206
- static int
207
- L2SqrI4x(const void *__restrict pVect1, const void *__restrict pVect2, const void *__restrict qty_ptr) {
208
-
209
- size_t qty = *((size_t *) qty_ptr);
210
- int res = 0;
211
- unsigned char *a = (unsigned char *) pVect1;
212
- unsigned char *b = (unsigned char *) pVect2;
213
-
214
- qty = qty >> 2;
215
- for (size_t i = 0; i < qty; i++) {
216
-
217
- res += ((*a) - (*b)) * ((*a) - (*b));
218
- a++;
219
- b++;
220
- res += ((*a) - (*b)) * ((*a) - (*b));
221
- a++;
222
- b++;
223
- res += ((*a) - (*b)) * ((*a) - (*b));
224
- a++;
225
- b++;
226
- res += ((*a) - (*b)) * ((*a) - (*b));
227
- a++;
228
- b++;
229
- }
230
- return (res);
208
+ class L2Space : public SpaceInterface<float> {
209
+ DISTFUNC<float> fstdistfunc_;
210
+ size_t data_size_;
211
+ size_t dim_;
212
+
213
+ public:
214
+ L2Space(size_t dim) {
215
+ fstdistfunc_ = L2Sqr;
216
+ #if defined(USE_SSE) || defined(USE_AVX) || defined(USE_AVX512)
217
+ #if defined(USE_AVX512)
218
+ if (AVX512Capable())
219
+ L2SqrSIMD16Ext = L2SqrSIMD16ExtAVX512;
220
+ else if (AVXCapable())
221
+ L2SqrSIMD16Ext = L2SqrSIMD16ExtAVX;
222
+ #elif defined(USE_AVX)
223
+ if (AVXCapable())
224
+ L2SqrSIMD16Ext = L2SqrSIMD16ExtAVX;
225
+ #endif
226
+
227
+ if (dim % 16 == 0)
228
+ fstdistfunc_ = L2SqrSIMD16Ext;
229
+ else if (dim % 4 == 0)
230
+ fstdistfunc_ = L2SqrSIMD4Ext;
231
+ else if (dim > 16)
232
+ fstdistfunc_ = L2SqrSIMD16ExtResiduals;
233
+ else if (dim > 4)
234
+ fstdistfunc_ = L2SqrSIMD4ExtResiduals;
235
+ #endif
236
+ dim_ = dim;
237
+ data_size_ = dim * sizeof(float);
231
238
  }
232
239
 
233
- static int L2SqrI(const void* __restrict pVect1, const void* __restrict pVect2, const void* __restrict qty_ptr) {
234
- size_t qty = *((size_t*)qty_ptr);
235
- int res = 0;
236
- unsigned char* a = (unsigned char*)pVect1;
237
- unsigned char* b = (unsigned char*)pVect2;
238
-
239
- for(size_t i = 0; i < qty; i++)
240
- {
241
- res += ((*a) - (*b)) * ((*a) - (*b));
242
- a++;
243
- b++;
244
- }
245
- return (res);
240
+ size_t get_data_size() {
241
+ return data_size_;
246
242
  }
247
243
 
248
- class L2SpaceI : public SpaceInterface<int> {
249
-
250
- DISTFUNC<int> fstdistfunc_;
251
- size_t data_size_;
252
- size_t dim_;
253
- public:
254
- L2SpaceI(size_t dim) {
255
- if(dim % 4 == 0) {
256
- fstdistfunc_ = L2SqrI4x;
257
- }
258
- else {
259
- fstdistfunc_ = L2SqrI;
260
- }
261
- dim_ = dim;
262
- data_size_ = dim * sizeof(unsigned char);
263
- }
244
+ DISTFUNC<float> get_dist_func() {
245
+ return fstdistfunc_;
246
+ }
264
247
 
265
- size_t get_data_size() {
266
- return data_size_;
267
- }
248
+ void *get_dist_func_param() {
249
+ return &dim_;
250
+ }
268
251
 
269
- DISTFUNC<int> get_dist_func() {
270
- return fstdistfunc_;
252
+ ~L2Space() {}
253
+ };
254
+
255
+ static int
256
+ L2SqrI4x(const void *__restrict pVect1, const void *__restrict pVect2, const void *__restrict qty_ptr) {
257
+ size_t qty = *((size_t *) qty_ptr);
258
+ int res = 0;
259
+ unsigned char *a = (unsigned char *) pVect1;
260
+ unsigned char *b = (unsigned char *) pVect2;
261
+
262
+ qty = qty >> 2;
263
+ for (size_t i = 0; i < qty; i++) {
264
+ res += ((*a) - (*b)) * ((*a) - (*b));
265
+ a++;
266
+ b++;
267
+ res += ((*a) - (*b)) * ((*a) - (*b));
268
+ a++;
269
+ b++;
270
+ res += ((*a) - (*b)) * ((*a) - (*b));
271
+ a++;
272
+ b++;
273
+ res += ((*a) - (*b)) * ((*a) - (*b));
274
+ a++;
275
+ b++;
276
+ }
277
+ return (res);
278
+ }
279
+
280
+ static int L2SqrI(const void* __restrict pVect1, const void* __restrict pVect2, const void* __restrict qty_ptr) {
281
+ size_t qty = *((size_t*)qty_ptr);
282
+ int res = 0;
283
+ unsigned char* a = (unsigned char*)pVect1;
284
+ unsigned char* b = (unsigned char*)pVect2;
285
+
286
+ for (size_t i = 0; i < qty; i++) {
287
+ res += ((*a) - (*b)) * ((*a) - (*b));
288
+ a++;
289
+ b++;
290
+ }
291
+ return (res);
292
+ }
293
+
294
+ class L2SpaceI : public SpaceInterface<int> {
295
+ DISTFUNC<int> fstdistfunc_;
296
+ size_t data_size_;
297
+ size_t dim_;
298
+
299
+ public:
300
+ L2SpaceI(size_t dim) {
301
+ if (dim % 4 == 0) {
302
+ fstdistfunc_ = L2SqrI4x;
303
+ } else {
304
+ fstdistfunc_ = L2SqrI;
271
305
  }
306
+ dim_ = dim;
307
+ data_size_ = dim * sizeof(unsigned char);
308
+ }
272
309
 
273
- void *get_dist_func_param() {
274
- return &dim_;
275
- }
310
+ size_t get_data_size() {
311
+ return data_size_;
312
+ }
276
313
 
277
- ~L2SpaceI() {}
278
- };
314
+ DISTFUNC<int> get_dist_func() {
315
+ return fstdistfunc_;
316
+ }
279
317
 
318
+ void *get_dist_func_param() {
319
+ return &dim_;
320
+ }
280
321
 
281
- }
322
+ ~L2SpaceI() {}
323
+ };
324
+ } // namespace hnswlib
@@ -5,75 +5,74 @@
5
5
  #include <deque>
6
6
 
7
7
  namespace hnswlib {
8
- typedef unsigned short int vl_type;
8
+ typedef unsigned short int vl_type;
9
9
 
10
- class VisitedList {
11
- public:
12
- vl_type curV;
13
- vl_type *mass;
14
- unsigned int numelements;
10
+ class VisitedList {
11
+ public:
12
+ vl_type curV;
13
+ vl_type *mass;
14
+ unsigned int numelements;
15
15
 
16
- VisitedList(int numelements1) {
17
- curV = -1;
18
- numelements = numelements1;
19
- mass = new vl_type[numelements];
20
- }
16
+ VisitedList(int numelements1) {
17
+ curV = -1;
18
+ numelements = numelements1;
19
+ mass = new vl_type[numelements];
20
+ }
21
21
 
22
- void reset() {
22
+ void reset() {
23
+ curV++;
24
+ if (curV == 0) {
25
+ memset(mass, 0, sizeof(vl_type) * numelements);
23
26
  curV++;
24
- if (curV == 0) {
25
- memset(mass, 0, sizeof(vl_type) * numelements);
26
- curV++;
27
- }
28
- };
27
+ }
28
+ }
29
29
 
30
- ~VisitedList() { delete[] mass; }
31
- };
30
+ ~VisitedList() { delete[] mass; }
31
+ };
32
32
  ///////////////////////////////////////////////////////////
33
33
  //
34
34
  // Class for multi-threaded pool-management of VisitedLists
35
35
  //
36
36
  /////////////////////////////////////////////////////////
37
37
 
38
- class VisitedListPool {
39
- std::deque<VisitedList *> pool;
40
- std::mutex poolguard;
41
- int numelements;
42
-
43
- public:
44
- VisitedListPool(int initmaxpools, int numelements1) {
45
- numelements = numelements1;
46
- for (int i = 0; i < initmaxpools; i++)
47
- pool.push_front(new VisitedList(numelements));
48
- }
38
+ class VisitedListPool {
39
+ std::deque<VisitedList *> pool;
40
+ std::mutex poolguard;
41
+ int numelements;
49
42
 
50
- VisitedList *getFreeVisitedList() {
51
- VisitedList *rez;
52
- {
53
- std::unique_lock <std::mutex> lock(poolguard);
54
- if (pool.size() > 0) {
55
- rez = pool.front();
56
- pool.pop_front();
57
- } else {
58
- rez = new VisitedList(numelements);
59
- }
60
- }
61
- rez->reset();
62
- return rez;
63
- };
43
+ public:
44
+ VisitedListPool(int initmaxpools, int numelements1) {
45
+ numelements = numelements1;
46
+ for (int i = 0; i < initmaxpools; i++)
47
+ pool.push_front(new VisitedList(numelements));
48
+ }
64
49
 
65
- void releaseVisitedList(VisitedList *vl) {
50
+ VisitedList *getFreeVisitedList() {
51
+ VisitedList *rez;
52
+ {
66
53
  std::unique_lock <std::mutex> lock(poolguard);
67
- pool.push_front(vl);
68
- };
69
-
70
- ~VisitedListPool() {
71
- while (pool.size()) {
72
- VisitedList *rez = pool.front();
54
+ if (pool.size() > 0) {
55
+ rez = pool.front();
73
56
  pool.pop_front();
74
- delete rez;
57
+ } else {
58
+ rez = new VisitedList(numelements);
75
59
  }
76
- };
77
- };
78
- }
60
+ }
61
+ rez->reset();
62
+ return rez;
63
+ }
79
64
 
65
+ void releaseVisitedList(VisitedList *vl) {
66
+ std::unique_lock <std::mutex> lock(poolguard);
67
+ pool.push_front(vl);
68
+ }
69
+
70
+ ~VisitedListPool() {
71
+ while (pool.size()) {
72
+ VisitedList *rez = pool.front();
73
+ pool.pop_front();
74
+ delete rez;
75
+ }
76
+ }
77
+ };
78
+ } // namespace hnswlib