faiss 0.2.0 → 0.2.4

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.
Files changed (215) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +7 -7
  5. data/ext/faiss/extconf.rb +6 -3
  6. data/ext/faiss/numo.hpp +4 -4
  7. data/ext/faiss/utils.cpp +1 -1
  8. data/ext/faiss/utils.h +1 -1
  9. data/lib/faiss/version.rb +1 -1
  10. data/vendor/faiss/faiss/AutoTune.cpp +292 -291
  11. data/vendor/faiss/faiss/AutoTune.h +55 -56
  12. data/vendor/faiss/faiss/Clustering.cpp +365 -194
  13. data/vendor/faiss/faiss/Clustering.h +102 -35
  14. data/vendor/faiss/faiss/IVFlib.cpp +171 -195
  15. data/vendor/faiss/faiss/IVFlib.h +48 -51
  16. data/vendor/faiss/faiss/Index.cpp +85 -103
  17. data/vendor/faiss/faiss/Index.h +54 -48
  18. data/vendor/faiss/faiss/Index2Layer.cpp +126 -224
  19. data/vendor/faiss/faiss/Index2Layer.h +22 -36
  20. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +407 -0
  21. data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +195 -0
  22. data/vendor/faiss/faiss/IndexBinary.cpp +45 -37
  23. data/vendor/faiss/faiss/IndexBinary.h +140 -132
  24. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +73 -53
  25. data/vendor/faiss/faiss/IndexBinaryFlat.h +29 -24
  26. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +46 -43
  27. data/vendor/faiss/faiss/IndexBinaryFromFloat.h +16 -15
  28. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +215 -232
  29. data/vendor/faiss/faiss/IndexBinaryHNSW.h +25 -24
  30. data/vendor/faiss/faiss/IndexBinaryHash.cpp +182 -177
  31. data/vendor/faiss/faiss/IndexBinaryHash.h +41 -34
  32. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +489 -461
  33. data/vendor/faiss/faiss/IndexBinaryIVF.h +97 -68
  34. data/vendor/faiss/faiss/IndexFlat.cpp +115 -176
  35. data/vendor/faiss/faiss/IndexFlat.h +42 -59
  36. data/vendor/faiss/faiss/IndexFlatCodes.cpp +67 -0
  37. data/vendor/faiss/faiss/IndexFlatCodes.h +47 -0
  38. data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
  39. data/vendor/faiss/faiss/IndexHNSW.h +57 -41
  40. data/vendor/faiss/faiss/IndexIVF.cpp +545 -453
  41. data/vendor/faiss/faiss/IndexIVF.h +169 -118
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +316 -0
  43. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +121 -0
  44. data/vendor/faiss/faiss/IndexIVFFlat.cpp +247 -252
  45. data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
  46. data/vendor/faiss/faiss/IndexIVFPQ.cpp +459 -517
  47. data/vendor/faiss/faiss/IndexIVFPQ.h +75 -67
  48. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +406 -372
  49. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +82 -57
  50. data/vendor/faiss/faiss/IndexIVFPQR.cpp +104 -102
  51. data/vendor/faiss/faiss/IndexIVFPQR.h +33 -28
  52. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +163 -150
  53. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +38 -25
  54. data/vendor/faiss/faiss/IndexLSH.cpp +66 -113
  55. data/vendor/faiss/faiss/IndexLSH.h +20 -38
  56. data/vendor/faiss/faiss/IndexLattice.cpp +42 -56
  57. data/vendor/faiss/faiss/IndexLattice.h +11 -16
  58. data/vendor/faiss/faiss/IndexNNDescent.cpp +229 -0
  59. data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
  60. data/vendor/faiss/faiss/IndexNSG.cpp +301 -0
  61. data/vendor/faiss/faiss/IndexNSG.h +85 -0
  62. data/vendor/faiss/faiss/IndexPQ.cpp +387 -495
  63. data/vendor/faiss/faiss/IndexPQ.h +64 -82
  64. data/vendor/faiss/faiss/IndexPQFastScan.cpp +143 -170
  65. data/vendor/faiss/faiss/IndexPQFastScan.h +46 -32
  66. data/vendor/faiss/faiss/IndexPreTransform.cpp +120 -150
  67. data/vendor/faiss/faiss/IndexPreTransform.h +33 -36
  68. data/vendor/faiss/faiss/IndexRefine.cpp +139 -127
  69. data/vendor/faiss/faiss/IndexRefine.h +32 -23
  70. data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
  71. data/vendor/faiss/faiss/IndexReplicas.h +62 -56
  72. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +111 -172
  73. data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -59
  74. data/vendor/faiss/faiss/IndexShards.cpp +256 -240
  75. data/vendor/faiss/faiss/IndexShards.h +85 -73
  76. data/vendor/faiss/faiss/MatrixStats.cpp +112 -97
  77. data/vendor/faiss/faiss/MatrixStats.h +7 -10
  78. data/vendor/faiss/faiss/MetaIndexes.cpp +135 -157
  79. data/vendor/faiss/faiss/MetaIndexes.h +40 -34
  80. data/vendor/faiss/faiss/MetricType.h +7 -7
  81. data/vendor/faiss/faiss/VectorTransform.cpp +654 -475
  82. data/vendor/faiss/faiss/VectorTransform.h +64 -89
  83. data/vendor/faiss/faiss/clone_index.cpp +78 -73
  84. data/vendor/faiss/faiss/clone_index.h +4 -9
  85. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +33 -38
  86. data/vendor/faiss/faiss/gpu/GpuAutoTune.h +11 -9
  87. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +198 -171
  88. data/vendor/faiss/faiss/gpu/GpuCloner.h +53 -35
  89. data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +12 -14
  90. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +27 -25
  91. data/vendor/faiss/faiss/gpu/GpuDistance.h +116 -112
  92. data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -2
  93. data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +60 -0
  94. data/vendor/faiss/faiss/gpu/GpuIndex.h +134 -137
  95. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +76 -73
  96. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +173 -162
  97. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +67 -64
  98. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +89 -86
  99. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +150 -141
  100. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +101 -103
  101. data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +17 -16
  102. data/vendor/faiss/faiss/gpu/GpuResources.cpp +116 -128
  103. data/vendor/faiss/faiss/gpu/GpuResources.h +182 -186
  104. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +433 -422
  105. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +131 -130
  106. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +468 -456
  107. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +25 -19
  108. data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +22 -20
  109. data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +9 -8
  110. data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +39 -44
  111. data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +16 -14
  112. data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +77 -71
  113. data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +109 -88
  114. data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +75 -64
  115. data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +230 -215
  116. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +80 -86
  117. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +284 -277
  118. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +416 -416
  119. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +611 -517
  120. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +166 -164
  121. data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +61 -53
  122. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +274 -238
  123. data/vendor/faiss/faiss/gpu/test/TestUtils.h +73 -57
  124. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +47 -50
  125. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +79 -72
  126. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +140 -146
  127. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +69 -71
  128. data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +21 -16
  129. data/vendor/faiss/faiss/gpu/utils/Timer.cpp +25 -29
  130. data/vendor/faiss/faiss/gpu/utils/Timer.h +30 -29
  131. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +503 -0
  132. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +175 -0
  133. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +90 -120
  134. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +81 -65
  135. data/vendor/faiss/faiss/impl/FaissAssert.h +73 -58
  136. data/vendor/faiss/faiss/impl/FaissException.cpp +56 -48
  137. data/vendor/faiss/faiss/impl/FaissException.h +41 -29
  138. data/vendor/faiss/faiss/impl/HNSW.cpp +606 -617
  139. data/vendor/faiss/faiss/impl/HNSW.h +179 -200
  140. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +855 -0
  141. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +244 -0
  142. data/vendor/faiss/faiss/impl/NNDescent.cpp +487 -0
  143. data/vendor/faiss/faiss/impl/NNDescent.h +154 -0
  144. data/vendor/faiss/faiss/impl/NSG.cpp +679 -0
  145. data/vendor/faiss/faiss/impl/NSG.h +199 -0
  146. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +484 -454
  147. data/vendor/faiss/faiss/impl/PolysemousTraining.h +52 -55
  148. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +26 -47
  149. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +469 -459
  150. data/vendor/faiss/faiss/impl/ProductQuantizer.h +76 -87
  151. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +758 -0
  152. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +188 -0
  153. data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
  154. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +647 -707
  155. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +48 -46
  156. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +129 -131
  157. data/vendor/faiss/faiss/impl/ThreadedIndex.h +61 -55
  158. data/vendor/faiss/faiss/impl/index_read.cpp +631 -480
  159. data/vendor/faiss/faiss/impl/index_write.cpp +547 -407
  160. data/vendor/faiss/faiss/impl/io.cpp +76 -95
  161. data/vendor/faiss/faiss/impl/io.h +31 -41
  162. data/vendor/faiss/faiss/impl/io_macros.h +60 -29
  163. data/vendor/faiss/faiss/impl/kmeans1d.cpp +301 -0
  164. data/vendor/faiss/faiss/impl/kmeans1d.h +48 -0
  165. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +137 -186
  166. data/vendor/faiss/faiss/impl/lattice_Zn.h +40 -51
  167. data/vendor/faiss/faiss/impl/platform_macros.h +29 -8
  168. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +77 -124
  169. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +39 -48
  170. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +41 -52
  171. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +80 -117
  172. data/vendor/faiss/faiss/impl/simd_result_handlers.h +109 -137
  173. data/vendor/faiss/faiss/index_factory.cpp +619 -397
  174. data/vendor/faiss/faiss/index_factory.h +8 -6
  175. data/vendor/faiss/faiss/index_io.h +23 -26
  176. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +67 -75
  177. data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +22 -24
  178. data/vendor/faiss/faiss/invlists/DirectMap.cpp +96 -112
  179. data/vendor/faiss/faiss/invlists/DirectMap.h +29 -33
  180. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +307 -364
  181. data/vendor/faiss/faiss/invlists/InvertedLists.h +151 -151
  182. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +29 -34
  183. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +17 -18
  184. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +257 -293
  185. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +50 -45
  186. data/vendor/faiss/faiss/python/python_callbacks.cpp +23 -26
  187. data/vendor/faiss/faiss/python/python_callbacks.h +9 -16
  188. data/vendor/faiss/faiss/utils/AlignedTable.h +79 -44
  189. data/vendor/faiss/faiss/utils/Heap.cpp +40 -48
  190. data/vendor/faiss/faiss/utils/Heap.h +186 -209
  191. data/vendor/faiss/faiss/utils/WorkerThread.cpp +67 -76
  192. data/vendor/faiss/faiss/utils/WorkerThread.h +32 -33
  193. data/vendor/faiss/faiss/utils/distances.cpp +305 -312
  194. data/vendor/faiss/faiss/utils/distances.h +170 -122
  195. data/vendor/faiss/faiss/utils/distances_simd.cpp +498 -508
  196. data/vendor/faiss/faiss/utils/extra_distances-inl.h +117 -0
  197. data/vendor/faiss/faiss/utils/extra_distances.cpp +113 -232
  198. data/vendor/faiss/faiss/utils/extra_distances.h +30 -29
  199. data/vendor/faiss/faiss/utils/hamming-inl.h +260 -209
  200. data/vendor/faiss/faiss/utils/hamming.cpp +375 -469
  201. data/vendor/faiss/faiss/utils/hamming.h +62 -85
  202. data/vendor/faiss/faiss/utils/ordered_key_value.h +16 -18
  203. data/vendor/faiss/faiss/utils/partitioning.cpp +393 -318
  204. data/vendor/faiss/faiss/utils/partitioning.h +26 -21
  205. data/vendor/faiss/faiss/utils/quantize_lut.cpp +78 -66
  206. data/vendor/faiss/faiss/utils/quantize_lut.h +22 -20
  207. data/vendor/faiss/faiss/utils/random.cpp +39 -63
  208. data/vendor/faiss/faiss/utils/random.h +13 -16
  209. data/vendor/faiss/faiss/utils/simdlib.h +4 -2
  210. data/vendor/faiss/faiss/utils/simdlib_avx2.h +88 -85
  211. data/vendor/faiss/faiss/utils/simdlib_emulated.h +226 -165
  212. data/vendor/faiss/faiss/utils/simdlib_neon.h +832 -0
  213. data/vendor/faiss/faiss/utils/utils.cpp +304 -287
  214. data/vendor/faiss/faiss/utils/utils.h +54 -49
  215. metadata +29 -4
@@ -9,316 +9,299 @@
9
9
 
10
10
  #include <faiss/IndexBinaryHNSW.h>
11
11
 
12
-
13
- #include <memory>
14
- #include <cstdlib>
12
+ #include <omp.h>
15
13
  #include <cassert>
16
- #include <cstring>
17
- #include <cstdio>
18
14
  #include <cmath>
19
- #include <omp.h>
15
+ #include <cstdio>
16
+ #include <cstdlib>
17
+ #include <cstring>
18
+ #include <memory>
20
19
 
21
- #include <unordered_set>
22
20
  #include <queue>
21
+ #include <unordered_set>
23
22
 
24
- #include <sys/types.h>
25
- #include <sys/stat.h>
26
23
  #include <stdint.h>
24
+ #include <sys/stat.h>
25
+ #include <sys/types.h>
27
26
 
28
- #include <faiss/utils/random.h>
29
- #include <faiss/utils/Heap.h>
30
- #include <faiss/impl/FaissAssert.h>
31
27
  #include <faiss/IndexBinaryFlat.h>
32
- #include <faiss/utils/hamming.h>
33
28
  #include <faiss/impl/AuxIndexStructures.h>
29
+ #include <faiss/impl/FaissAssert.h>
30
+ #include <faiss/utils/Heap.h>
31
+ #include <faiss/utils/hamming.h>
32
+ #include <faiss/utils/random.h>
34
33
 
35
34
  namespace faiss {
36
35
 
37
-
38
36
  /**************************************************************
39
37
  * add / search blocks of descriptors
40
38
  **************************************************************/
41
39
 
42
40
  namespace {
43
41
 
42
+ void hnsw_add_vertices(
43
+ IndexBinaryHNSW& index_hnsw,
44
+ size_t n0,
45
+ size_t n,
46
+ const uint8_t* x,
47
+ bool verbose,
48
+ bool preset_levels = false) {
49
+ HNSW& hnsw = index_hnsw.hnsw;
50
+ size_t ntotal = n0 + n;
51
+ double t0 = getmillisecs();
52
+ if (verbose) {
53
+ printf("hnsw_add_vertices: adding %zd elements on top of %zd "
54
+ "(preset_levels=%d)\n",
55
+ n,
56
+ n0,
57
+ int(preset_levels));
58
+ }
59
+
60
+ int max_level = hnsw.prepare_level_tab(n, preset_levels);
44
61
 
45
- void hnsw_add_vertices(IndexBinaryHNSW& index_hnsw,
46
- size_t n0,
47
- size_t n, const uint8_t *x,
48
- bool verbose,
49
- bool preset_levels = false) {
50
- HNSW& hnsw = index_hnsw.hnsw;
51
- size_t ntotal = n0 + n;
52
- double t0 = getmillisecs();
53
- if (verbose) {
54
- printf("hnsw_add_vertices: adding %zd elements on top of %zd "
55
- "(preset_levels=%d)\n",
56
- n, n0, int(preset_levels));
57
- }
58
-
59
- int max_level = hnsw.prepare_level_tab(n, preset_levels);
60
-
61
- if (verbose) {
62
- printf(" max_level = %d\n", max_level);
63
- }
64
-
65
- std::vector<omp_lock_t> locks(ntotal);
66
- for(int i = 0; i < ntotal; i++) {
67
- omp_init_lock(&locks[i]);
68
- }
69
-
70
- // add vectors from highest to lowest level
71
- std::vector<int> hist;
72
- std::vector<int> order(n);
73
-
74
- { // make buckets with vectors of the same level
75
-
76
- // build histogram
77
- for (int i = 0; i < n; i++) {
78
- HNSW::storage_idx_t pt_id = i + n0;
79
- int pt_level = hnsw.levels[pt_id] - 1;
80
- while (pt_level >= hist.size()) {
81
- hist.push_back(0);
82
- }
83
- hist[pt_level] ++;
62
+ if (verbose) {
63
+ printf(" max_level = %d\n", max_level);
84
64
  }
85
65
 
86
- // accumulate
87
- std::vector<int> offsets(hist.size() + 1, 0);
88
- for (int i = 0; i < hist.size() - 1; i++) {
89
- offsets[i + 1] = offsets[i] + hist[i];
66
+ std::vector<omp_lock_t> locks(ntotal);
67
+ for (int i = 0; i < ntotal; i++) {
68
+ omp_init_lock(&locks[i]);
90
69
  }
91
70
 
92
- // bucket sort
93
- for (int i = 0; i < n; i++) {
94
- HNSW::storage_idx_t pt_id = i + n0;
95
- int pt_level = hnsw.levels[pt_id] - 1;
96
- order[offsets[pt_level]++] = pt_id;
71
+ // add vectors from highest to lowest level
72
+ std::vector<int> hist;
73
+ std::vector<int> order(n);
74
+
75
+ { // make buckets with vectors of the same level
76
+
77
+ // build histogram
78
+ for (int i = 0; i < n; i++) {
79
+ HNSW::storage_idx_t pt_id = i + n0;
80
+ int pt_level = hnsw.levels[pt_id] - 1;
81
+ while (pt_level >= hist.size()) {
82
+ hist.push_back(0);
83
+ }
84
+ hist[pt_level]++;
85
+ }
86
+
87
+ // accumulate
88
+ std::vector<int> offsets(hist.size() + 1, 0);
89
+ for (int i = 0; i < hist.size() - 1; i++) {
90
+ offsets[i + 1] = offsets[i] + hist[i];
91
+ }
92
+
93
+ // bucket sort
94
+ for (int i = 0; i < n; i++) {
95
+ HNSW::storage_idx_t pt_id = i + n0;
96
+ int pt_level = hnsw.levels[pt_id] - 1;
97
+ order[offsets[pt_level]++] = pt_id;
98
+ }
97
99
  }
98
- }
99
100
 
100
- { // perform add
101
- RandomGenerator rng2(789);
101
+ { // perform add
102
+ RandomGenerator rng2(789);
102
103
 
103
- int i1 = n;
104
+ int i1 = n;
104
105
 
105
- for (int pt_level = hist.size() - 1; pt_level >= 0; pt_level--) {
106
- int i0 = i1 - hist[pt_level];
106
+ for (int pt_level = hist.size() - 1; pt_level >= 0; pt_level--) {
107
+ int i0 = i1 - hist[pt_level];
107
108
 
108
- if (verbose) {
109
- printf("Adding %d elements at level %d\n",
110
- i1 - i0, pt_level);
111
- }
109
+ if (verbose) {
110
+ printf("Adding %d elements at level %d\n", i1 - i0, pt_level);
111
+ }
112
112
 
113
- // random permutation to get rid of dataset order bias
114
- for (int j = i0; j < i1; j++) {
115
- std::swap(order[j], order[j + rng2.rand_int(i1 - j)]);
116
- }
113
+ // random permutation to get rid of dataset order bias
114
+ for (int j = i0; j < i1; j++) {
115
+ std::swap(order[j], order[j + rng2.rand_int(i1 - j)]);
116
+ }
117
117
 
118
118
  #pragma omp parallel
119
- {
120
- VisitedTable vt (ntotal);
121
-
122
- std::unique_ptr<DistanceComputer> dis(
123
- index_hnsw.get_distance_computer()
124
- );
125
- int prev_display = verbose && omp_get_thread_num() == 0 ? 0 : -1;
126
-
127
- #pragma omp for schedule(dynamic)
128
- for (int i = i0; i < i1; i++) {
129
- HNSW::storage_idx_t pt_id = order[i];
130
- dis->set_query((float *)(x + (pt_id - n0) * index_hnsw.code_size));
131
-
132
- hnsw.add_with_locks(*dis, pt_level, pt_id, locks, vt);
133
-
134
- if (prev_display >= 0 && i - i0 > prev_display + 10000) {
135
- prev_display = i - i0;
136
- printf(" %d / %d\r", i - i0, i1 - i0);
137
- fflush(stdout);
138
- }
119
+ {
120
+ VisitedTable vt(ntotal);
121
+
122
+ std::unique_ptr<DistanceComputer> dis(
123
+ index_hnsw.get_distance_computer());
124
+ int prev_display =
125
+ verbose && omp_get_thread_num() == 0 ? 0 : -1;
126
+
127
+ #pragma omp for schedule(dynamic)
128
+ for (int i = i0; i < i1; i++) {
129
+ HNSW::storage_idx_t pt_id = order[i];
130
+ dis->set_query(
131
+ (float*)(x + (pt_id - n0) * index_hnsw.code_size));
132
+
133
+ hnsw.add_with_locks(*dis, pt_level, pt_id, locks, vt);
134
+
135
+ if (prev_display >= 0 && i - i0 > prev_display + 10000) {
136
+ prev_display = i - i0;
137
+ printf(" %d / %d\r", i - i0, i1 - i0);
138
+ fflush(stdout);
139
+ }
140
+ }
141
+ }
142
+ i1 = i0;
139
143
  }
140
- }
141
- i1 = i0;
144
+ FAISS_ASSERT(i1 == 0);
145
+ }
146
+ if (verbose) {
147
+ printf("Done in %.3f ms\n", getmillisecs() - t0);
142
148
  }
143
- FAISS_ASSERT(i1 == 0);
144
- }
145
- if (verbose) {
146
- printf("Done in %.3f ms\n", getmillisecs() - t0);
147
- }
148
-
149
- for(int i = 0; i < ntotal; i++)
150
- omp_destroy_lock(&locks[i]);
151
- }
152
149
 
150
+ for (int i = 0; i < ntotal; i++)
151
+ omp_destroy_lock(&locks[i]);
152
+ }
153
153
 
154
154
  } // anonymous namespace
155
155
 
156
-
157
156
  /**************************************************************
158
157
  * IndexBinaryHNSW implementation
159
158
  **************************************************************/
160
159
 
161
- IndexBinaryHNSW::IndexBinaryHNSW()
162
- {
163
- is_trained = true;
160
+ IndexBinaryHNSW::IndexBinaryHNSW() {
161
+ is_trained = true;
164
162
  }
165
163
 
166
164
  IndexBinaryHNSW::IndexBinaryHNSW(int d, int M)
167
- : IndexBinary(d),
168
- hnsw(M),
169
- own_fields(true),
170
- storage(new IndexBinaryFlat(d))
171
- {
172
- is_trained = true;
165
+ : IndexBinary(d),
166
+ hnsw(M),
167
+ own_fields(true),
168
+ storage(new IndexBinaryFlat(d)) {
169
+ is_trained = true;
173
170
  }
174
171
 
175
- IndexBinaryHNSW::IndexBinaryHNSW(IndexBinary *storage, int M)
176
- : IndexBinary(storage->d),
177
- hnsw(M),
178
- own_fields(false),
179
- storage(storage)
180
- {
181
- is_trained = true;
172
+ IndexBinaryHNSW::IndexBinaryHNSW(IndexBinary* storage, int M)
173
+ : IndexBinary(storage->d),
174
+ hnsw(M),
175
+ own_fields(false),
176
+ storage(storage) {
177
+ is_trained = true;
182
178
  }
183
179
 
184
180
  IndexBinaryHNSW::~IndexBinaryHNSW() {
185
- if (own_fields) {
186
- delete storage;
187
- }
181
+ if (own_fields) {
182
+ delete storage;
183
+ }
188
184
  }
189
185
 
190
- void IndexBinaryHNSW::train(idx_t n, const uint8_t *x)
191
- {
192
- // hnsw structure does not require training
193
- storage->train(n, x);
194
- is_trained = true;
186
+ void IndexBinaryHNSW::train(idx_t n, const uint8_t* x) {
187
+ // hnsw structure does not require training
188
+ storage->train(n, x);
189
+ is_trained = true;
195
190
  }
196
191
 
197
- void IndexBinaryHNSW::search(idx_t n, const uint8_t *x, idx_t k,
198
- int32_t *distances, idx_t *labels) const
199
- {
192
+ void IndexBinaryHNSW::search(
193
+ idx_t n,
194
+ const uint8_t* x,
195
+ idx_t k,
196
+ int32_t* distances,
197
+ idx_t* labels) const {
198
+ FAISS_THROW_IF_NOT(k > 0);
199
+
200
200
  #pragma omp parallel
201
- {
202
- VisitedTable vt(ntotal);
203
- std::unique_ptr<DistanceComputer> dis(get_distance_computer());
201
+ {
202
+ VisitedTable vt(ntotal);
203
+ std::unique_ptr<DistanceComputer> dis(get_distance_computer());
204
204
 
205
205
  #pragma omp for
206
- for(idx_t i = 0; i < n; i++) {
207
- idx_t *idxi = labels + i * k;
208
- float *simi = (float *)(distances + i * k);
206
+ for (idx_t i = 0; i < n; i++) {
207
+ idx_t* idxi = labels + i * k;
208
+ float* simi = (float*)(distances + i * k);
209
209
 
210
- dis->set_query((float *)(x + i * code_size));
210
+ dis->set_query((float*)(x + i * code_size));
211
211
 
212
- maxheap_heapify(k, simi, idxi);
213
- hnsw.search(*dis, k, idxi, simi, vt);
214
- maxheap_reorder(k, simi, idxi);
212
+ maxheap_heapify(k, simi, idxi);
213
+ hnsw.search(*dis, k, idxi, simi, vt);
214
+ maxheap_reorder(k, simi, idxi);
215
+ }
215
216
  }
216
- }
217
217
 
218
218
  #pragma omp parallel for
219
- for (int i = 0; i < n * k; ++i) {
220
- distances[i] = std::round(((float *)distances)[i]);
221
- }
219
+ for (int i = 0; i < n * k; ++i) {
220
+ distances[i] = std::round(((float*)distances)[i]);
221
+ }
222
222
  }
223
223
 
224
+ void IndexBinaryHNSW::add(idx_t n, const uint8_t* x) {
225
+ FAISS_THROW_IF_NOT(is_trained);
226
+ int n0 = ntotal;
227
+ storage->add(n, x);
228
+ ntotal = storage->ntotal;
224
229
 
225
- void IndexBinaryHNSW::add(idx_t n, const uint8_t *x)
226
- {
227
- FAISS_THROW_IF_NOT(is_trained);
228
- int n0 = ntotal;
229
- storage->add(n, x);
230
- ntotal = storage->ntotal;
231
-
232
- hnsw_add_vertices(*this, n0, n, x, verbose,
233
- hnsw.levels.size() == ntotal);
230
+ hnsw_add_vertices(*this, n0, n, x, verbose, hnsw.levels.size() == ntotal);
234
231
  }
235
232
 
236
- void IndexBinaryHNSW::reset()
237
- {
238
- hnsw.reset();
239
- storage->reset();
240
- ntotal = 0;
233
+ void IndexBinaryHNSW::reset() {
234
+ hnsw.reset();
235
+ storage->reset();
236
+ ntotal = 0;
241
237
  }
242
238
 
243
- void IndexBinaryHNSW::reconstruct(idx_t key, uint8_t *recons) const
244
- {
245
- storage->reconstruct(key, recons);
239
+ void IndexBinaryHNSW::reconstruct(idx_t key, uint8_t* recons) const {
240
+ storage->reconstruct(key, recons);
246
241
  }
247
242
 
248
-
249
243
  namespace {
250
244
 
251
-
252
- template<class HammingComputer>
245
+ template <class HammingComputer>
253
246
  struct FlatHammingDis : DistanceComputer {
254
- const int code_size;
255
- const uint8_t *b;
256
- size_t ndis;
257
- HammingComputer hc;
258
-
259
- float operator () (idx_t i) override {
260
- ndis++;
261
- return hc.hamming(b + i * code_size);
262
- }
263
-
264
- float symmetric_dis(idx_t i, idx_t j) override {
265
- return HammingComputerDefault(b + j * code_size, code_size)
266
- .hamming(b + i * code_size);
267
- }
268
-
269
-
270
- explicit FlatHammingDis(const IndexBinaryFlat& storage)
271
- : code_size(storage.code_size),
272
- b(storage.xb.data()),
273
- ndis(0),
274
- hc() {}
275
-
276
- // NOTE: Pointers are cast from float in order to reuse the floating-point
277
- // DistanceComputer.
278
- void set_query(const float *x) override {
279
- hc.set((uint8_t *)x, code_size);
280
- }
281
-
282
- ~FlatHammingDis() override {
247
+ const int code_size;
248
+ const uint8_t* b;
249
+ size_t ndis;
250
+ HammingComputer hc;
251
+
252
+ float operator()(idx_t i) override {
253
+ ndis++;
254
+ return hc.hamming(b + i * code_size);
255
+ }
256
+
257
+ float symmetric_dis(idx_t i, idx_t j) override {
258
+ return HammingComputerDefault(b + j * code_size, code_size)
259
+ .hamming(b + i * code_size);
260
+ }
261
+
262
+ explicit FlatHammingDis(const IndexBinaryFlat& storage)
263
+ : code_size(storage.code_size),
264
+ b(storage.xb.data()),
265
+ ndis(0),
266
+ hc() {}
267
+
268
+ // NOTE: Pointers are cast from float in order to reuse the floating-point
269
+ // DistanceComputer.
270
+ void set_query(const float* x) override {
271
+ hc.set((uint8_t*)x, code_size);
272
+ }
273
+
274
+ ~FlatHammingDis() override {
283
275
  #pragma omp critical
284
- {
285
- hnsw_stats.ndis += ndis;
276
+ { hnsw_stats.ndis += ndis; }
286
277
  }
287
- }
288
278
  };
289
279
 
280
+ } // namespace
281
+
282
+ DistanceComputer* IndexBinaryHNSW::get_distance_computer() const {
283
+ IndexBinaryFlat* flat_storage = dynamic_cast<IndexBinaryFlat*>(storage);
284
+
285
+ FAISS_ASSERT(flat_storage != nullptr);
286
+
287
+ switch (code_size) {
288
+ case 4:
289
+ return new FlatHammingDis<HammingComputer4>(*flat_storage);
290
+ case 8:
291
+ return new FlatHammingDis<HammingComputer8>(*flat_storage);
292
+ case 16:
293
+ return new FlatHammingDis<HammingComputer16>(*flat_storage);
294
+ case 20:
295
+ return new FlatHammingDis<HammingComputer20>(*flat_storage);
296
+ case 32:
297
+ return new FlatHammingDis<HammingComputer32>(*flat_storage);
298
+ case 64:
299
+ return new FlatHammingDis<HammingComputer64>(*flat_storage);
300
+ default:
301
+ break;
302
+ }
290
303
 
291
- } // namespace
292
-
293
-
294
- DistanceComputer *IndexBinaryHNSW::get_distance_computer() const {
295
- IndexBinaryFlat *flat_storage = dynamic_cast<IndexBinaryFlat *>(storage);
296
-
297
- FAISS_ASSERT(flat_storage != nullptr);
298
-
299
- switch(code_size) {
300
- case 4:
301
- return new FlatHammingDis<HammingComputer4>(*flat_storage);
302
- case 8:
303
- return new FlatHammingDis<HammingComputer8>(*flat_storage);
304
- case 16:
305
- return new FlatHammingDis<HammingComputer16>(*flat_storage);
306
- case 20:
307
- return new FlatHammingDis<HammingComputer20>(*flat_storage);
308
- case 32:
309
- return new FlatHammingDis<HammingComputer32>(*flat_storage);
310
- case 64:
311
- return new FlatHammingDis<HammingComputer64>(*flat_storage);
312
- default:
313
- if (code_size % 8 == 0) {
314
- return new FlatHammingDis<HammingComputerM8>(*flat_storage);
315
- } else if (code_size % 4 == 0) {
316
- return new FlatHammingDis<HammingComputerM4>(*flat_storage);
317
- }
318
- }
319
-
320
- return new FlatHammingDis<HammingComputerDefault>(*flat_storage);
304
+ return new FlatHammingDis<HammingComputerDefault>(*flat_storage);
321
305
  }
322
306
 
323
-
324
307
  } // namespace faiss
@@ -9,48 +9,49 @@
9
9
 
10
10
  #pragma once
11
11
 
12
- #include <faiss/impl/HNSW.h>
13
12
  #include <faiss/IndexBinaryFlat.h>
13
+ #include <faiss/impl/HNSW.h>
14
14
  #include <faiss/utils/utils.h>
15
15
 
16
-
17
16
  namespace faiss {
18
17
 
19
-
20
18
  /** The HNSW index is a normal random-access index with a HNSW
21
19
  * link structure built on top */
22
20
 
23
21
  struct IndexBinaryHNSW : IndexBinary {
24
- typedef HNSW::storage_idx_t storage_idx_t;
22
+ typedef HNSW::storage_idx_t storage_idx_t;
25
23
 
26
- // the link strcuture
27
- HNSW hnsw;
24
+ // the link strcuture
25
+ HNSW hnsw;
28
26
 
29
- // the sequential storage
30
- bool own_fields;
31
- IndexBinary *storage;
27
+ // the sequential storage
28
+ bool own_fields;
29
+ IndexBinary* storage;
32
30
 
33
- explicit IndexBinaryHNSW();
34
- explicit IndexBinaryHNSW(int d, int M = 32);
35
- explicit IndexBinaryHNSW(IndexBinary *storage, int M = 32);
31
+ explicit IndexBinaryHNSW();
32
+ explicit IndexBinaryHNSW(int d, int M = 32);
33
+ explicit IndexBinaryHNSW(IndexBinary* storage, int M = 32);
36
34
 
37
- ~IndexBinaryHNSW() override;
35
+ ~IndexBinaryHNSW() override;
38
36
 
39
- DistanceComputer *get_distance_computer() const;
37
+ DistanceComputer* get_distance_computer() const;
40
38
 
41
- void add(idx_t n, const uint8_t *x) override;
39
+ void add(idx_t n, const uint8_t* x) override;
42
40
 
43
- /// Trains the storage if needed
44
- void train(idx_t n, const uint8_t* x) override;
41
+ /// Trains the storage if needed
42
+ void train(idx_t n, const uint8_t* x) override;
45
43
 
46
- /// entry point for search
47
- void search(idx_t n, const uint8_t *x, idx_t k,
48
- int32_t *distances, idx_t *labels) const override;
44
+ /// entry point for search
45
+ void search(
46
+ idx_t n,
47
+ const uint8_t* x,
48
+ idx_t k,
49
+ int32_t* distances,
50
+ idx_t* labels) const override;
49
51
 
50
- void reconstruct(idx_t key, uint8_t* recons) const override;
52
+ void reconstruct(idx_t key, uint8_t* recons) const override;
51
53
 
52
- void reset() override;
54
+ void reset() override;
53
55
  };
54
56
 
55
-
56
- } // namespace faiss
57
+ } // namespace faiss