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
@@ -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