faiss 0.1.7 → 0.2.3

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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/README.md +7 -7
  4. data/ext/faiss/ext.cpp +1 -1
  5. data/ext/faiss/extconf.rb +8 -2
  6. data/ext/faiss/index.cpp +102 -69
  7. data/ext/faiss/index_binary.cpp +24 -30
  8. data/ext/faiss/kmeans.cpp +20 -16
  9. data/ext/faiss/numo.hpp +867 -0
  10. data/ext/faiss/pca_matrix.cpp +13 -14
  11. data/ext/faiss/product_quantizer.cpp +23 -24
  12. data/ext/faiss/utils.cpp +10 -37
  13. data/ext/faiss/utils.h +2 -13
  14. data/lib/faiss/version.rb +1 -1
  15. data/lib/faiss.rb +0 -5
  16. data/vendor/faiss/faiss/AutoTune.cpp +292 -291
  17. data/vendor/faiss/faiss/AutoTune.h +55 -56
  18. data/vendor/faiss/faiss/Clustering.cpp +334 -195
  19. data/vendor/faiss/faiss/Clustering.h +88 -35
  20. data/vendor/faiss/faiss/IVFlib.cpp +171 -195
  21. data/vendor/faiss/faiss/IVFlib.h +48 -51
  22. data/vendor/faiss/faiss/Index.cpp +85 -103
  23. data/vendor/faiss/faiss/Index.h +54 -48
  24. data/vendor/faiss/faiss/Index2Layer.cpp +139 -164
  25. data/vendor/faiss/faiss/Index2Layer.h +22 -22
  26. data/vendor/faiss/faiss/IndexBinary.cpp +45 -37
  27. data/vendor/faiss/faiss/IndexBinary.h +140 -132
  28. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +73 -53
  29. data/vendor/faiss/faiss/IndexBinaryFlat.h +29 -24
  30. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +46 -43
  31. data/vendor/faiss/faiss/IndexBinaryFromFloat.h +16 -15
  32. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +215 -232
  33. data/vendor/faiss/faiss/IndexBinaryHNSW.h +25 -24
  34. data/vendor/faiss/faiss/IndexBinaryHash.cpp +182 -177
  35. data/vendor/faiss/faiss/IndexBinaryHash.h +41 -34
  36. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +489 -461
  37. data/vendor/faiss/faiss/IndexBinaryIVF.h +97 -68
  38. data/vendor/faiss/faiss/IndexFlat.cpp +116 -147
  39. data/vendor/faiss/faiss/IndexFlat.h +35 -46
  40. data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
  41. data/vendor/faiss/faiss/IndexHNSW.h +57 -41
  42. data/vendor/faiss/faiss/IndexIVF.cpp +474 -454
  43. data/vendor/faiss/faiss/IndexIVF.h +146 -113
  44. data/vendor/faiss/faiss/IndexIVFFlat.cpp +248 -250
  45. data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
  46. data/vendor/faiss/faiss/IndexIVFPQ.cpp +457 -516
  47. data/vendor/faiss/faiss/IndexIVFPQ.h +74 -66
  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 +125 -133
  53. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +19 -21
  54. data/vendor/faiss/faiss/IndexLSH.cpp +75 -96
  55. data/vendor/faiss/faiss/IndexLSH.h +21 -26
  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 +231 -0
  59. data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
  60. data/vendor/faiss/faiss/IndexNSG.cpp +303 -0
  61. data/vendor/faiss/faiss/IndexNSG.h +85 -0
  62. data/vendor/faiss/faiss/IndexPQ.cpp +405 -464
  63. data/vendor/faiss/faiss/IndexPQ.h +64 -67
  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 +115 -131
  69. data/vendor/faiss/faiss/IndexRefine.h +22 -23
  70. data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
  71. data/vendor/faiss/faiss/IndexReplicas.h +62 -56
  72. data/vendor/faiss/faiss/IndexResidual.cpp +291 -0
  73. data/vendor/faiss/faiss/IndexResidual.h +152 -0
  74. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +120 -155
  75. data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -45
  76. data/vendor/faiss/faiss/IndexShards.cpp +256 -240
  77. data/vendor/faiss/faiss/IndexShards.h +85 -73
  78. data/vendor/faiss/faiss/MatrixStats.cpp +112 -97
  79. data/vendor/faiss/faiss/MatrixStats.h +7 -10
  80. data/vendor/faiss/faiss/MetaIndexes.cpp +135 -157
  81. data/vendor/faiss/faiss/MetaIndexes.h +40 -34
  82. data/vendor/faiss/faiss/MetricType.h +7 -7
  83. data/vendor/faiss/faiss/VectorTransform.cpp +652 -474
  84. data/vendor/faiss/faiss/VectorTransform.h +61 -89
  85. data/vendor/faiss/faiss/clone_index.cpp +77 -73
  86. data/vendor/faiss/faiss/clone_index.h +4 -9
  87. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +33 -38
  88. data/vendor/faiss/faiss/gpu/GpuAutoTune.h +11 -9
  89. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +197 -170
  90. data/vendor/faiss/faiss/gpu/GpuCloner.h +53 -35
  91. data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +12 -14
  92. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +27 -25
  93. data/vendor/faiss/faiss/gpu/GpuDistance.h +116 -112
  94. data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -2
  95. data/vendor/faiss/faiss/gpu/GpuIndex.h +134 -137
  96. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +76 -73
  97. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +173 -162
  98. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +67 -64
  99. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +89 -86
  100. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +150 -141
  101. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +101 -103
  102. data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +17 -16
  103. data/vendor/faiss/faiss/gpu/GpuResources.cpp +116 -128
  104. data/vendor/faiss/faiss/gpu/GpuResources.h +182 -186
  105. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +433 -422
  106. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +131 -130
  107. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +468 -456
  108. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +25 -19
  109. data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +22 -20
  110. data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +9 -8
  111. data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +39 -44
  112. data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +16 -14
  113. data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +77 -71
  114. data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +109 -88
  115. data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +75 -64
  116. data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +230 -215
  117. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +80 -86
  118. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +284 -277
  119. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +416 -416
  120. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +611 -517
  121. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +166 -164
  122. data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +61 -53
  123. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +274 -238
  124. data/vendor/faiss/faiss/gpu/test/TestUtils.h +73 -57
  125. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +47 -50
  126. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +79 -72
  127. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +140 -146
  128. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +69 -71
  129. data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +21 -16
  130. data/vendor/faiss/faiss/gpu/utils/Timer.cpp +25 -29
  131. data/vendor/faiss/faiss/gpu/utils/Timer.h +30 -29
  132. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +270 -0
  133. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +115 -0
  134. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +90 -120
  135. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +81 -65
  136. data/vendor/faiss/faiss/impl/FaissAssert.h +73 -58
  137. data/vendor/faiss/faiss/impl/FaissException.cpp +56 -48
  138. data/vendor/faiss/faiss/impl/FaissException.h +41 -29
  139. data/vendor/faiss/faiss/impl/HNSW.cpp +595 -611
  140. data/vendor/faiss/faiss/impl/HNSW.h +179 -200
  141. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +672 -0
  142. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +172 -0
  143. data/vendor/faiss/faiss/impl/NNDescent.cpp +487 -0
  144. data/vendor/faiss/faiss/impl/NNDescent.h +154 -0
  145. data/vendor/faiss/faiss/impl/NSG.cpp +682 -0
  146. data/vendor/faiss/faiss/impl/NSG.h +199 -0
  147. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +484 -454
  148. data/vendor/faiss/faiss/impl/PolysemousTraining.h +52 -55
  149. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +26 -47
  150. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +469 -459
  151. data/vendor/faiss/faiss/impl/ProductQuantizer.h +76 -87
  152. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +448 -0
  153. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +130 -0
  154. data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
  155. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +648 -701
  156. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +48 -46
  157. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +129 -131
  158. data/vendor/faiss/faiss/impl/ThreadedIndex.h +61 -55
  159. data/vendor/faiss/faiss/impl/index_read.cpp +547 -479
  160. data/vendor/faiss/faiss/impl/index_write.cpp +497 -407
  161. data/vendor/faiss/faiss/impl/io.cpp +75 -94
  162. data/vendor/faiss/faiss/impl/io.h +31 -41
  163. data/vendor/faiss/faiss/impl/io_macros.h +40 -29
  164. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +137 -186
  165. data/vendor/faiss/faiss/impl/lattice_Zn.h +40 -51
  166. data/vendor/faiss/faiss/impl/platform_macros.h +29 -8
  167. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +77 -124
  168. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +39 -48
  169. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +41 -52
  170. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +80 -117
  171. data/vendor/faiss/faiss/impl/simd_result_handlers.h +109 -137
  172. data/vendor/faiss/faiss/index_factory.cpp +269 -218
  173. data/vendor/faiss/faiss/index_factory.h +6 -7
  174. data/vendor/faiss/faiss/index_io.h +23 -26
  175. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +67 -75
  176. data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +22 -24
  177. data/vendor/faiss/faiss/invlists/DirectMap.cpp +96 -112
  178. data/vendor/faiss/faiss/invlists/DirectMap.h +29 -33
  179. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +307 -364
  180. data/vendor/faiss/faiss/invlists/InvertedLists.h +151 -151
  181. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +29 -34
  182. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +17 -18
  183. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +257 -293
  184. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +50 -45
  185. data/vendor/faiss/faiss/python/python_callbacks.cpp +23 -26
  186. data/vendor/faiss/faiss/python/python_callbacks.h +9 -16
  187. data/vendor/faiss/faiss/utils/AlignedTable.h +79 -44
  188. data/vendor/faiss/faiss/utils/Heap.cpp +40 -48
  189. data/vendor/faiss/faiss/utils/Heap.h +186 -209
  190. data/vendor/faiss/faiss/utils/WorkerThread.cpp +67 -76
  191. data/vendor/faiss/faiss/utils/WorkerThread.h +32 -33
  192. data/vendor/faiss/faiss/utils/distances.cpp +301 -310
  193. data/vendor/faiss/faiss/utils/distances.h +133 -118
  194. data/vendor/faiss/faiss/utils/distances_simd.cpp +456 -516
  195. data/vendor/faiss/faiss/utils/extra_distances-inl.h +117 -0
  196. data/vendor/faiss/faiss/utils/extra_distances.cpp +113 -232
  197. data/vendor/faiss/faiss/utils/extra_distances.h +30 -29
  198. data/vendor/faiss/faiss/utils/hamming-inl.h +260 -209
  199. data/vendor/faiss/faiss/utils/hamming.cpp +375 -469
  200. data/vendor/faiss/faiss/utils/hamming.h +62 -85
  201. data/vendor/faiss/faiss/utils/ordered_key_value.h +16 -18
  202. data/vendor/faiss/faiss/utils/partitioning.cpp +393 -318
  203. data/vendor/faiss/faiss/utils/partitioning.h +26 -21
  204. data/vendor/faiss/faiss/utils/quantize_lut.cpp +78 -66
  205. data/vendor/faiss/faiss/utils/quantize_lut.h +22 -20
  206. data/vendor/faiss/faiss/utils/random.cpp +39 -63
  207. data/vendor/faiss/faiss/utils/random.h +13 -16
  208. data/vendor/faiss/faiss/utils/simdlib.h +4 -2
  209. data/vendor/faiss/faiss/utils/simdlib_avx2.h +88 -85
  210. data/vendor/faiss/faiss/utils/simdlib_emulated.h +226 -165
  211. data/vendor/faiss/faiss/utils/simdlib_neon.h +832 -0
  212. data/vendor/faiss/faiss/utils/utils.cpp +304 -287
  213. data/vendor/faiss/faiss/utils/utils.h +53 -48
  214. metadata +26 -12
  215. data/lib/faiss/index.rb +0 -20
  216. data/lib/faiss/index_binary.rb +0 -20
  217. data/lib/faiss/kmeans.rb +0 -15
  218. data/lib/faiss/pca_matrix.rb +0 -15
  219. data/lib/faiss/product_quantizer.rb +0 -22
@@ -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