faiss 0.1.5 → 0.2.2

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 +24 -0
  3. data/README.md +12 -0
  4. data/ext/faiss/ext.cpp +1 -1
  5. data/ext/faiss/extconf.rb +6 -2
  6. data/ext/faiss/index.cpp +114 -43
  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.rb +0 -5
  15. data/lib/faiss/version.rb +1 -1
  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 +24 -10
  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,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
@@ -22,44 +22,42 @@
22
22
 
23
23
  namespace faiss {
24
24
 
25
- void IndexBinaryHash::InvertedList::add (
26
- idx_t id, size_t code_size, const uint8_t *code)
27
- {
25
+ void IndexBinaryHash::InvertedList::add(
26
+ idx_t id,
27
+ size_t code_size,
28
+ const uint8_t* code) {
28
29
  ids.push_back(id);
29
30
  vecs.insert(vecs.end(), code, code + code_size);
30
31
  }
31
32
 
32
- IndexBinaryHash::IndexBinaryHash(int d, int b):
33
- IndexBinary(d), b(b), nflip(0)
34
- {
33
+ IndexBinaryHash::IndexBinaryHash(int d, int b)
34
+ : IndexBinary(d), b(b), nflip(0) {
35
35
  is_trained = true;
36
36
  }
37
37
 
38
- IndexBinaryHash::IndexBinaryHash(): b(0), nflip(0)
39
- {
38
+ IndexBinaryHash::IndexBinaryHash() : b(0), nflip(0) {
40
39
  is_trained = true;
41
40
  }
42
41
 
43
- void IndexBinaryHash::reset()
44
- {
42
+ void IndexBinaryHash::reset() {
45
43
  invlists.clear();
46
44
  ntotal = 0;
47
45
  }
48
46
 
49
-
50
- void IndexBinaryHash::add(idx_t n, const uint8_t *x)
51
- {
47
+ void IndexBinaryHash::add(idx_t n, const uint8_t* x) {
52
48
  add_with_ids(n, x, nullptr);
53
49
  }
54
50
 
55
- void IndexBinaryHash::add_with_ids(idx_t n, const uint8_t *x, const idx_t *xids)
56
- {
51
+ void IndexBinaryHash::add_with_ids(
52
+ idx_t n,
53
+ const uint8_t* x,
54
+ const idx_t* xids) {
57
55
  uint64_t mask = ((uint64_t)1 << b) - 1;
58
56
  // simplistic add function. Cannot really be parallelized.
59
57
 
60
58
  for (idx_t i = 0; i < n; i++) {
61
59
  idx_t id = xids ? xids[i] : ntotal + i;
62
- const uint8_t * xi = x + i * code_size;
60
+ const uint8_t* xi = x + i * code_size;
63
61
  idx_t hash = *((uint64_t*)xi) & mask;
64
62
  invlists[hash].add(id, code_size, xi);
65
63
  }
@@ -68,7 +66,6 @@ void IndexBinaryHash::add_with_ids(idx_t n, const uint8_t *x, const idx_t *xids)
68
66
 
69
67
  namespace {
70
68
 
71
-
72
69
  /** Enumerate all bit vectors of size nbit with up to maxflip 1s
73
70
  * test in P127257851 P127258235
74
71
  */
@@ -76,7 +73,7 @@ struct FlipEnumerator {
76
73
  int nbit, nflip, maxflip;
77
74
  uint64_t mask, x;
78
75
 
79
- FlipEnumerator (int nbit, int maxflip): nbit(nbit), maxflip(maxflip) {
76
+ FlipEnumerator(int nbit, int maxflip) : nbit(nbit), maxflip(maxflip) {
80
77
  nflip = 0;
81
78
  mask = 0;
82
79
  x = 0;
@@ -108,128 +105,133 @@ struct FlipEnumerator {
108
105
  }
109
106
  return true;
110
107
  }
111
-
112
108
  };
113
109
 
114
110
  using idx_t = Index::idx_t;
115
111
 
116
-
117
112
  struct RangeSearchResults {
118
113
  int radius;
119
- RangeQueryResult &qres;
114
+ RangeQueryResult& qres;
120
115
 
121
- inline void add (float dis, idx_t id) {
116
+ inline void add(float dis, idx_t id) {
122
117
  if (dis < radius) {
123
- qres.add (dis, id);
118
+ qres.add(dis, id);
124
119
  }
125
120
  }
126
-
127
121
  };
128
122
 
129
123
  struct KnnSearchResults {
130
124
  // heap params
131
125
  idx_t k;
132
- int32_t * heap_sim;
133
- idx_t * heap_ids;
126
+ int32_t* heap_sim;
127
+ idx_t* heap_ids;
134
128
 
135
129
  using C = CMax<int, idx_t>;
136
130
 
137
- inline void add (float dis, idx_t id) {
131
+ inline void add(float dis, idx_t id) {
138
132
  if (dis < heap_sim[0]) {
139
- heap_replace_top<C> (k, heap_sim, heap_ids, dis, id);
133
+ heap_replace_top<C>(k, heap_sim, heap_ids, dis, id);
140
134
  }
141
135
  }
142
-
143
136
  };
144
137
 
145
- template<class HammingComputer, class SearchResults>
146
- void
147
- search_single_query_template(const IndexBinaryHash & index, const uint8_t *q,
148
- SearchResults &res,
149
- size_t &n0, size_t &nlist, size_t &ndis)
150
- {
138
+ template <class HammingComputer, class SearchResults>
139
+ void search_single_query_template(
140
+ const IndexBinaryHash& index,
141
+ const uint8_t* q,
142
+ SearchResults& res,
143
+ size_t& n0,
144
+ size_t& nlist,
145
+ size_t& ndis) {
151
146
  size_t code_size = index.code_size;
152
147
  uint64_t mask = ((uint64_t)1 << index.b) - 1;
153
148
  uint64_t qhash = *((uint64_t*)q) & mask;
154
- HammingComputer hc (q, code_size);
149
+ HammingComputer hc(q, code_size);
155
150
  FlipEnumerator fe(index.b, index.nflip);
156
151
 
157
152
  // loop over neighbors that are at most at nflip bits
158
153
  do {
159
154
  uint64_t hash = qhash ^ fe.x;
160
- auto it = index.invlists.find (hash);
155
+ auto it = index.invlists.find(hash);
161
156
 
162
157
  if (it == index.invlists.end()) {
163
158
  continue;
164
159
  }
165
160
 
166
- const IndexBinaryHash::InvertedList &il = it->second;
161
+ const IndexBinaryHash::InvertedList& il = it->second;
167
162
 
168
163
  size_t nv = il.ids.size();
169
164
 
170
165
  if (nv == 0) {
171
166
  n0++;
172
167
  } else {
173
- const uint8_t *codes = il.vecs.data();
168
+ const uint8_t* codes = il.vecs.data();
174
169
  for (size_t i = 0; i < nv; i++) {
175
- int dis = hc.hamming (codes);
170
+ int dis = hc.hamming(codes);
176
171
  res.add(dis, il.ids[i]);
177
172
  codes += code_size;
178
173
  }
179
174
  ndis += nv;
180
175
  nlist++;
181
176
  }
182
- } while(fe.next());
177
+ } while (fe.next());
183
178
  }
184
179
 
185
- template<class SearchResults>
186
- void
187
- search_single_query(const IndexBinaryHash & index, const uint8_t *q,
188
- SearchResults &res,
189
- size_t &n0, size_t &nlist, size_t &ndis)
190
- {
191
- #define HC(name) search_single_query_template<name>(index, q, res, n0, nlist, ndis);
192
- switch(index.code_size) {
193
- case 4: HC(HammingComputer4); break;
194
- case 8: HC(HammingComputer8); break;
195
- case 16: HC(HammingComputer16); break;
196
- case 20: HC(HammingComputer20); break;
197
- case 32: HC(HammingComputer32); break;
198
- default:
199
- if (index.code_size % 8 == 0) {
200
- HC(HammingComputerM8);
201
- } else {
180
+ template <class SearchResults>
181
+ void search_single_query(
182
+ const IndexBinaryHash& index,
183
+ const uint8_t* q,
184
+ SearchResults& res,
185
+ size_t& n0,
186
+ size_t& nlist,
187
+ size_t& ndis) {
188
+ #define HC(name) \
189
+ search_single_query_template<name>(index, q, res, n0, nlist, ndis);
190
+ switch (index.code_size) {
191
+ case 4:
192
+ HC(HammingComputer4);
193
+ break;
194
+ case 8:
195
+ HC(HammingComputer8);
196
+ break;
197
+ case 16:
198
+ HC(HammingComputer16);
199
+ break;
200
+ case 20:
201
+ HC(HammingComputer20);
202
+ break;
203
+ case 32:
204
+ HC(HammingComputer32);
205
+ break;
206
+ default:
202
207
  HC(HammingComputerDefault);
203
- }
208
+ break;
204
209
  }
205
210
  #undef HC
206
211
  }
207
212
 
208
-
209
213
  } // anonymous namespace
210
214
 
211
-
212
-
213
- void IndexBinaryHash::range_search(idx_t n, const uint8_t *x, int radius,
214
- RangeSearchResult *result) const
215
- {
216
-
215
+ void IndexBinaryHash::range_search(
216
+ idx_t n,
217
+ const uint8_t* x,
218
+ int radius,
219
+ RangeSearchResult* result) const {
217
220
  size_t nlist = 0, ndis = 0, n0 = 0;
218
221
 
219
- #pragma omp parallel if(n > 100) reduction(+: ndis, n0, nlist)
222
+ #pragma omp parallel if (n > 100) reduction(+ : ndis, n0, nlist)
220
223
  {
221
- RangeSearchPartialResult pres (result);
224
+ RangeSearchPartialResult pres(result);
222
225
 
223
226
  #pragma omp for
224
227
  for (idx_t i = 0; i < n; i++) { // loop queries
225
- RangeQueryResult & qres = pres.new_result (i);
228
+ RangeQueryResult& qres = pres.new_result(i);
226
229
  RangeSearchResults res = {radius, qres};
227
- const uint8_t *q = x + i * code_size;
228
-
229
- search_single_query (*this, q, res, n0, nlist, ndis);
230
+ const uint8_t* q = x + i * code_size;
230
231
 
232
+ search_single_query(*this, q, res, n0, nlist, ndis);
231
233
  }
232
- pres.finalize ();
234
+ pres.finalize();
233
235
  }
234
236
  indexBinaryHash_stats.nq += n;
235
237
  indexBinaryHash_stats.n0 += n0;
@@ -237,24 +239,29 @@ void IndexBinaryHash::range_search(idx_t n, const uint8_t *x, int radius,
237
239
  indexBinaryHash_stats.ndis += ndis;
238
240
  }
239
241
 
240
- void IndexBinaryHash::search(idx_t n, const uint8_t *x, idx_t k,
241
- int32_t *distances, idx_t *labels) const
242
- {
242
+ void IndexBinaryHash::search(
243
+ idx_t n,
244
+ const uint8_t* x,
245
+ idx_t k,
246
+ int32_t* distances,
247
+ idx_t* labels) const {
248
+ FAISS_THROW_IF_NOT(k > 0);
243
249
 
244
250
  using HeapForL2 = CMax<int32_t, idx_t>;
245
251
  size_t nlist = 0, ndis = 0, n0 = 0;
246
252
 
247
- #pragma omp parallel for if(n > 100) reduction(+: nlist, ndis, n0)
253
+ #pragma omp parallel for if (n > 100) reduction(+ : nlist, ndis, n0)
248
254
  for (idx_t i = 0; i < n; i++) {
249
- int32_t * simi = distances + k * i;
250
- idx_t * idxi = labels + k * i;
255
+ int32_t* simi = distances + k * i;
256
+ idx_t* idxi = labels + k * i;
251
257
 
252
- heap_heapify<HeapForL2> (k, simi, idxi);
258
+ heap_heapify<HeapForL2>(k, simi, idxi);
253
259
  KnnSearchResults res = {k, simi, idxi};
254
- const uint8_t *q = x + i * code_size;
260
+ const uint8_t* q = x + i * code_size;
255
261
 
256
- search_single_query (*this, q, res, n0, nlist, ndis);
262
+ search_single_query(*this, q, res, n0, nlist, ndis);
257
263
 
264
+ heap_reorder<HeapForL2>(k, simi, idxi);
258
265
  }
259
266
  indexBinaryHash_stats.nq += n;
260
267
  indexBinaryHash_stats.n0 += n0;
@@ -262,29 +269,23 @@ void IndexBinaryHash::search(idx_t n, const uint8_t *x, idx_t k,
262
269
  indexBinaryHash_stats.ndis += ndis;
263
270
  }
264
271
 
265
- size_t IndexBinaryHash::hashtable_size() const
266
- {
272
+ size_t IndexBinaryHash::hashtable_size() const {
267
273
  return invlists.size();
268
274
  }
269
275
 
270
-
271
- void IndexBinaryHash::display() const
272
- {
276
+ void IndexBinaryHash::display() const {
273
277
  for (auto it = invlists.begin(); it != invlists.end(); ++it) {
274
278
  printf("%" PRId64 ": [", it->first);
275
- const std::vector<idx_t> & v = it->second.ids;
276
- for (auto x: v) {
279
+ const std::vector<idx_t>& v = it->second.ids;
280
+ for (auto x : v) {
277
281
  printf("%" PRId64 " ", x);
278
282
  }
279
283
  printf("]\n");
280
-
281
284
  }
282
285
  }
283
286
 
284
-
285
- void IndexBinaryHashStats::reset()
286
- {
287
- memset ((void*)this, 0, sizeof (*this));
287
+ void IndexBinaryHashStats::reset() {
288
+ memset((void*)this, 0, sizeof(*this));
288
289
  }
289
290
 
290
291
  IndexBinaryHashStats indexBinaryHash_stats;
@@ -293,47 +294,43 @@ IndexBinaryHashStats indexBinaryHash_stats;
293
294
  * IndexBinaryMultiHash implementation
294
295
  ******************************************************/
295
296
 
296
-
297
- IndexBinaryMultiHash::IndexBinaryMultiHash(int d, int nhash, int b):
298
- IndexBinary(d),
299
- storage(new IndexBinaryFlat(d)), own_fields(true),
300
- maps(nhash), nhash(nhash), b(b), nflip(0)
301
- {
297
+ IndexBinaryMultiHash::IndexBinaryMultiHash(int d, int nhash, int b)
298
+ : IndexBinary(d),
299
+ storage(new IndexBinaryFlat(d)),
300
+ own_fields(true),
301
+ maps(nhash),
302
+ nhash(nhash),
303
+ b(b),
304
+ nflip(0) {
302
305
  FAISS_THROW_IF_NOT(nhash * b <= d);
303
306
  }
304
307
 
305
- IndexBinaryMultiHash::IndexBinaryMultiHash():
306
- storage(nullptr), own_fields(true),
307
- nhash(0), b(0), nflip(0)
308
- {}
308
+ IndexBinaryMultiHash::IndexBinaryMultiHash()
309
+ : storage(nullptr), own_fields(true), nhash(0), b(0), nflip(0) {}
309
310
 
310
- IndexBinaryMultiHash::~IndexBinaryMultiHash()
311
- {
311
+ IndexBinaryMultiHash::~IndexBinaryMultiHash() {
312
312
  if (own_fields) {
313
313
  delete storage;
314
314
  }
315
315
  }
316
316
 
317
-
318
- void IndexBinaryMultiHash::reset()
319
- {
317
+ void IndexBinaryMultiHash::reset() {
320
318
  storage->reset();
321
319
  ntotal = 0;
322
- for(auto map: maps) {
320
+ for (auto map : maps) {
323
321
  map.clear();
324
322
  }
325
323
  }
326
324
 
327
- void IndexBinaryMultiHash::add(idx_t n, const uint8_t *x)
328
- {
325
+ void IndexBinaryMultiHash::add(idx_t n, const uint8_t* x) {
329
326
  storage->add(n, x);
330
327
  // populate maps
331
328
  uint64_t mask = ((uint64_t)1 << b) - 1;
332
329
 
333
- for(idx_t i = 0; i < n; i++) {
334
- const uint8_t *xi = x + i * code_size;
330
+ for (idx_t i = 0; i < n; i++) {
331
+ const uint8_t* xi = x + i * code_size;
335
332
  int ho = 0;
336
- for(int h = 0; h < nhash; h++) {
333
+ for (int h = 0; h < nhash; h++) {
337
334
  uint64_t hash = *(uint64_t*)(xi + (ho >> 3)) >> (ho & 7);
338
335
  hash &= mask;
339
336
  maps[h][hash].push_back(i + ntotal);
@@ -343,62 +340,60 @@ void IndexBinaryMultiHash::add(idx_t n, const uint8_t *x)
343
340
  ntotal += n;
344
341
  }
345
342
 
346
-
347
343
  namespace {
348
344
 
349
345
  template <class HammingComputer, class SearchResults>
350
- static
351
- void verify_shortlist(
352
- const IndexBinaryFlat & index,
353
- const uint8_t * q,
354
- const std::unordered_set<Index::idx_t> & shortlist,
355
- SearchResults &res)
356
- {
346
+ static void verify_shortlist(
347
+ const IndexBinaryFlat& index,
348
+ const uint8_t* q,
349
+ const std::unordered_set<Index::idx_t>& shortlist,
350
+ SearchResults& res) {
357
351
  size_t code_size = index.code_size;
358
352
  size_t nlist = 0, ndis = 0, n0 = 0;
359
353
 
360
- HammingComputer hc (q, code_size);
361
- const uint8_t *codes = index.xb.data();
354
+ HammingComputer hc(q, code_size);
355
+ const uint8_t* codes = index.xb.data();
362
356
 
363
- for (auto i: shortlist) {
364
- int dis = hc.hamming (codes + i * code_size);
357
+ for (auto i : shortlist) {
358
+ int dis = hc.hamming(codes + i * code_size);
365
359
  res.add(dis, i);
366
360
  }
367
361
  }
368
362
 
369
- template<class SearchResults>
370
- void
371
- search_1_query_multihash(const IndexBinaryMultiHash & index, const uint8_t *xi,
372
- SearchResults &res,
373
- size_t &n0, size_t &nlist, size_t &ndis)
374
- {
375
-
363
+ template <class SearchResults>
364
+ void search_1_query_multihash(
365
+ const IndexBinaryMultiHash& index,
366
+ const uint8_t* xi,
367
+ SearchResults& res,
368
+ size_t& n0,
369
+ size_t& nlist,
370
+ size_t& ndis) {
376
371
  std::unordered_set<idx_t> shortlist;
377
372
  int b = index.b;
378
373
  uint64_t mask = ((uint64_t)1 << b) - 1;
379
374
 
380
375
  int ho = 0;
381
- for(int h = 0; h < index.nhash; h++) {
376
+ for (int h = 0; h < index.nhash; h++) {
382
377
  uint64_t qhash = *(uint64_t*)(xi + (ho >> 3)) >> (ho & 7);
383
378
  qhash &= mask;
384
- const IndexBinaryMultiHash::Map & map = index.maps[h];
379
+ const IndexBinaryMultiHash::Map& map = index.maps[h];
385
380
 
386
381
  FlipEnumerator fe(index.b, index.nflip);
387
382
  // loop over neighbors that are at most at nflip bits
388
383
  do {
389
384
  uint64_t hash = qhash ^ fe.x;
390
- auto it = map.find (hash);
385
+ auto it = map.find(hash);
391
386
 
392
387
  if (it != map.end()) {
393
- const std::vector<idx_t> & v = it->second;
394
- for (auto i: v) {
388
+ const std::vector<idx_t>& v = it->second;
389
+ for (auto i : v) {
395
390
  shortlist.insert(i);
396
391
  }
397
392
  nlist++;
398
393
  } else {
399
394
  n0++;
400
395
  }
401
- } while(fe.next());
396
+ } while (fe.next());
402
397
 
403
398
  ho += b;
404
399
  }
@@ -406,45 +401,52 @@ search_1_query_multihash(const IndexBinaryMultiHash & index, const uint8_t *xi,
406
401
 
407
402
  // verify shortlist
408
403
 
409
- #define HC(name) verify_shortlist<name> (*index.storage, xi, shortlist, res)
410
- switch(index.code_size) {
411
- case 4: HC(HammingComputer4); break;
412
- case 8: HC(HammingComputer8); break;
413
- case 16: HC(HammingComputer16); break;
414
- case 20: HC(HammingComputer20); break;
415
- case 32: HC(HammingComputer32); break;
416
- default:
417
- if (index.code_size % 8 == 0) {
418
- HC(HammingComputerM8);
419
- } else {
404
+ #define HC(name) verify_shortlist<name>(*index.storage, xi, shortlist, res)
405
+ switch (index.code_size) {
406
+ case 4:
407
+ HC(HammingComputer4);
408
+ break;
409
+ case 8:
410
+ HC(HammingComputer8);
411
+ break;
412
+ case 16:
413
+ HC(HammingComputer16);
414
+ break;
415
+ case 20:
416
+ HC(HammingComputer20);
417
+ break;
418
+ case 32:
419
+ HC(HammingComputer32);
420
+ break;
421
+ default:
420
422
  HC(HammingComputerDefault);
421
- }
423
+ break;
422
424
  }
423
425
  #undef HC
424
426
  }
425
427
 
426
428
  } // anonymous namespace
427
429
 
428
- void IndexBinaryMultiHash::range_search(idx_t n, const uint8_t *x, int radius,
429
- RangeSearchResult *result) const
430
- {
431
-
430
+ void IndexBinaryMultiHash::range_search(
431
+ idx_t n,
432
+ const uint8_t* x,
433
+ int radius,
434
+ RangeSearchResult* result) const {
432
435
  size_t nlist = 0, ndis = 0, n0 = 0;
433
436
 
434
- #pragma omp parallel if(n > 100) reduction(+: ndis, n0, nlist)
437
+ #pragma omp parallel if (n > 100) reduction(+ : ndis, n0, nlist)
435
438
  {
436
- RangeSearchPartialResult pres (result);
439
+ RangeSearchPartialResult pres(result);
437
440
 
438
441
  #pragma omp for
439
442
  for (idx_t i = 0; i < n; i++) { // loop queries
440
- RangeQueryResult & qres = pres.new_result (i);
443
+ RangeQueryResult& qres = pres.new_result(i);
441
444
  RangeSearchResults res = {radius, qres};
442
- const uint8_t *q = x + i * code_size;
443
-
444
- search_1_query_multihash (*this, q, res, n0, nlist, ndis);
445
+ const uint8_t* q = x + i * code_size;
445
446
 
447
+ search_1_query_multihash(*this, q, res, n0, nlist, ndis);
446
448
  }
447
- pres.finalize ();
449
+ pres.finalize();
448
450
  }
449
451
  indexBinaryHash_stats.nq += n;
450
452
  indexBinaryHash_stats.n0 += n0;
@@ -452,24 +454,29 @@ void IndexBinaryMultiHash::range_search(idx_t n, const uint8_t *x, int radius,
452
454
  indexBinaryHash_stats.ndis += ndis;
453
455
  }
454
456
 
455
- void IndexBinaryMultiHash::search(idx_t n, const uint8_t *x, idx_t k,
456
- int32_t *distances, idx_t *labels) const
457
- {
457
+ void IndexBinaryMultiHash::search(
458
+ idx_t n,
459
+ const uint8_t* x,
460
+ idx_t k,
461
+ int32_t* distances,
462
+ idx_t* labels) const {
463
+ FAISS_THROW_IF_NOT(k > 0);
458
464
 
459
465
  using HeapForL2 = CMax<int32_t, idx_t>;
460
466
  size_t nlist = 0, ndis = 0, n0 = 0;
461
467
 
462
- #pragma omp parallel for if(n > 100) reduction(+: nlist, ndis, n0)
468
+ #pragma omp parallel for if (n > 100) reduction(+ : nlist, ndis, n0)
463
469
  for (idx_t i = 0; i < n; i++) {
464
- int32_t * simi = distances + k * i;
465
- idx_t * idxi = labels + k * i;
470
+ int32_t* simi = distances + k * i;
471
+ idx_t* idxi = labels + k * i;
466
472
 
467
- heap_heapify<HeapForL2> (k, simi, idxi);
473
+ heap_heapify<HeapForL2>(k, simi, idxi);
468
474
  KnnSearchResults res = {k, simi, idxi};
469
- const uint8_t *q = x + i * code_size;
475
+ const uint8_t* q = x + i * code_size;
470
476
 
471
- search_1_query_multihash (*this, q, res, n0, nlist, ndis);
477
+ search_1_query_multihash(*this, q, res, n0, nlist, ndis);
472
478
 
479
+ heap_reorder<HeapForL2>(k, simi, idxi);
473
480
  }
474
481
  indexBinaryHash_stats.nq += n;
475
482
  indexBinaryHash_stats.n0 += n0;
@@ -477,15 +484,13 @@ void IndexBinaryMultiHash::search(idx_t n, const uint8_t *x, idx_t k,
477
484
  indexBinaryHash_stats.ndis += ndis;
478
485
  }
479
486
 
480
- size_t IndexBinaryMultiHash::hashtable_size() const
481
- {
487
+ size_t IndexBinaryMultiHash::hashtable_size() const {
482
488
  size_t tot = 0;
483
- for (auto map: maps) {
489
+ for (auto map : maps) {
484
490
  tot += map.size();
485
491
  }
486
492
 
487
493
  return tot;
488
494
  }
489
495
 
490
-
491
- }
496
+ } // namespace faiss