faiss 0.1.5 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -22,200 +22,164 @@
22
22
  *
23
23
  * The hamdis_t should optimally be compatibe with one of the Torch Storage
24
24
  * (Byte,Short,Long) and therefore should be signed for 2-bytes and 4-bytes
25
- */
25
+ */
26
26
 
27
27
  #include <faiss/utils/hamming.h>
28
28
 
29
+ #include <math.h>
30
+ #include <stdio.h>
29
31
  #include <algorithm>
30
- #include <vector>
31
32
  #include <memory>
32
- #include <stdio.h>
33
- #include <math.h>
33
+ #include <vector>
34
34
 
35
- #include <faiss/utils/Heap.h>
35
+ #include <faiss/impl/AuxIndexStructures.h>
36
36
  #include <faiss/impl/FaissAssert.h>
37
+ #include <faiss/utils/Heap.h>
37
38
  #include <faiss/utils/utils.h>
38
- #include <faiss/impl/AuxIndexStructures.h>
39
39
 
40
40
  static const size_t BLOCKSIZE_QUERY = 8192;
41
41
 
42
-
43
42
  namespace faiss {
44
43
 
45
44
  size_t hamming_batch_size = 65536;
46
45
 
47
- static const uint8_t hamdis_tab_ham_bytes[256] = {
48
- 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
49
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
50
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
51
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
52
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
53
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
54
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
55
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
56
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
57
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
58
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
59
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
60
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
61
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
62
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
63
- 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
64
- };
65
-
46
+ const uint8_t hamdis_tab_ham_bytes[256] = {
47
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
48
+ 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
49
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
50
+ 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
51
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
52
+ 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
53
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
54
+ 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
55
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
56
+ 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
57
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
66
58
 
67
59
  /* Elementary Hamming distance computation: unoptimized */
68
60
  template <size_t nbits, typename T>
69
- T hamming (const uint8_t *bs1,
70
- const uint8_t *bs2)
71
- {
61
+ T hamming(const uint8_t* bs1, const uint8_t* bs2) {
72
62
  const size_t nbytes = nbits / 8;
73
63
  size_t i;
74
64
  T h = 0;
75
65
  for (i = 0; i < nbytes; i++)
76
- h += (T) hamdis_tab_ham_bytes[bs1[i]^bs2[i]];
66
+ h += (T)hamdis_tab_ham_bytes[bs1[i] ^ bs2[i]];
77
67
  return h;
78
68
  }
79
69
 
80
-
81
70
  /* Hamming distances for multiples of 64 bits */
82
71
  template <size_t nbits>
83
- hamdis_t hamming (const uint64_t * bs1, const uint64_t * bs2)
84
- {
72
+ hamdis_t hamming(const uint64_t* bs1, const uint64_t* bs2) {
85
73
  const size_t nwords = nbits / 64;
86
74
  size_t i;
87
75
  hamdis_t h = 0;
88
76
  for (i = 0; i < nwords; i++)
89
- h += popcount64 (bs1[i] ^ bs2[i]);
77
+ h += popcount64(bs1[i] ^ bs2[i]);
90
78
  return h;
91
79
  }
92
80
 
93
-
94
-
95
81
  /* specialized (optimized) functions */
96
82
  template <>
97
- hamdis_t hamming<64> (const uint64_t * pa, const uint64_t * pb)
98
- {
99
- return popcount64 (pa[0] ^ pb[0]);
83
+ hamdis_t hamming<64>(const uint64_t* pa, const uint64_t* pb) {
84
+ return popcount64(pa[0] ^ pb[0]);
100
85
  }
101
86
 
102
-
103
87
  template <>
104
- hamdis_t hamming<128> (const uint64_t *pa, const uint64_t *pb)
105
- {
106
- return popcount64 (pa[0] ^ pb[0]) + popcount64(pa[1] ^ pb[1]);
88
+ hamdis_t hamming<128>(const uint64_t* pa, const uint64_t* pb) {
89
+ return popcount64(pa[0] ^ pb[0]) + popcount64(pa[1] ^ pb[1]);
107
90
  }
108
91
 
109
-
110
92
  template <>
111
- hamdis_t hamming<256> (const uint64_t * pa, const uint64_t * pb)
112
- {
113
- return popcount64 (pa[0] ^ pb[0])
114
- + popcount64 (pa[1] ^ pb[1])
115
- + popcount64 (pa[2] ^ pb[2])
116
- + popcount64 (pa[3] ^ pb[3]);
93
+ hamdis_t hamming<256>(const uint64_t* pa, const uint64_t* pb) {
94
+ return popcount64(pa[0] ^ pb[0]) + popcount64(pa[1] ^ pb[1]) +
95
+ popcount64(pa[2] ^ pb[2]) + popcount64(pa[3] ^ pb[3]);
117
96
  }
118
97
 
119
-
120
98
  /* Hamming distances for multiple of 64 bits */
121
- hamdis_t hamming (
122
- const uint64_t * bs1,
123
- const uint64_t * bs2,
124
- size_t nwords)
125
- {
99
+ hamdis_t hamming(const uint64_t* bs1, const uint64_t* bs2, size_t nwords) {
126
100
  size_t i;
127
101
  hamdis_t h = 0;
128
102
  for (i = 0; i < nwords; i++)
129
- h += popcount64 (bs1[i] ^ bs2[i]);
103
+ h += popcount64(bs1[i] ^ bs2[i]);
130
104
  return h;
131
105
  }
132
106
 
133
-
134
-
135
107
  template <size_t nbits>
136
- void hammings (
137
- const uint64_t * bs1,
138
- const uint64_t * bs2,
139
- size_t n1, size_t n2,
140
- hamdis_t * dis)
108
+ void hammings(
109
+ const uint64_t* bs1,
110
+ const uint64_t* bs2,
111
+ size_t n1,
112
+ size_t n2,
113
+ hamdis_t* dis)
141
114
 
142
115
  {
143
116
  size_t i, j;
144
117
  const size_t nwords = nbits / 64;
145
118
  for (i = 0; i < n1; i++) {
146
- const uint64_t * __restrict bs1_ = bs1 + i * nwords;
147
- hamdis_t * __restrict dis_ = dis + i * n2;
119
+ const uint64_t* __restrict bs1_ = bs1 + i * nwords;
120
+ hamdis_t* __restrict dis_ = dis + i * n2;
148
121
  for (j = 0; j < n2; j++)
149
122
  dis_[j] = hamming<nbits>(bs1_, bs2 + j * nwords);
150
123
  }
151
124
  }
152
125
 
153
-
154
-
155
- void hammings (
156
- const uint64_t * bs1,
157
- const uint64_t * bs2,
126
+ void hammings(
127
+ const uint64_t* bs1,
128
+ const uint64_t* bs2,
158
129
  size_t n1,
159
130
  size_t n2,
160
131
  size_t nwords,
161
- hamdis_t * __restrict dis)
162
- {
132
+ hamdis_t* __restrict dis) {
163
133
  size_t i, j;
164
134
  n1 *= nwords;
165
135
  n2 *= nwords;
166
- for (i = 0; i < n1; i+=nwords) {
167
- const uint64_t * bs1_ = bs1+i;
168
- for (j = 0; j < n2; j+=nwords)
169
- dis[j] = hamming (bs1_, bs2+j, nwords);
136
+ for (i = 0; i < n1; i += nwords) {
137
+ const uint64_t* bs1_ = bs1 + i;
138
+ for (j = 0; j < n2; j += nwords)
139
+ dis[j] = hamming(bs1_, bs2 + j, nwords);
170
140
  }
171
141
  }
172
142
 
173
-
174
-
175
-
176
143
  /* Count number of matches given a max threshold */
177
144
  template <size_t nbits>
178
- void hamming_count_thres (
179
- const uint64_t * bs1,
180
- const uint64_t * bs2,
145
+ void hamming_count_thres(
146
+ const uint64_t* bs1,
147
+ const uint64_t* bs2,
181
148
  size_t n1,
182
149
  size_t n2,
183
150
  hamdis_t ht,
184
- size_t * nptr)
185
- {
151
+ size_t* nptr) {
186
152
  const size_t nwords = nbits / 64;
187
153
  size_t i, j, posm = 0;
188
- const uint64_t * bs2_ = bs2;
154
+ const uint64_t* bs2_ = bs2;
189
155
 
190
156
  for (i = 0; i < n1; i++) {
191
157
  bs2 = bs2_;
192
158
  for (j = 0; j < n2; j++) {
193
159
  /* collect the match only if this satisfies the threshold */
194
- if (hamming <nbits> (bs1, bs2) <= ht)
160
+ if (hamming<nbits>(bs1, bs2) <= ht)
195
161
  posm++;
196
162
  bs2 += nwords;
197
163
  }
198
- bs1 += nwords; /* next signature */
164
+ bs1 += nwords; /* next signature */
199
165
  }
200
166
  *nptr = posm;
201
167
  }
202
168
 
203
-
204
169
  template <size_t nbits>
205
- void crosshamming_count_thres (
206
- const uint64_t * dbs,
170
+ void crosshamming_count_thres(
171
+ const uint64_t* dbs,
207
172
  size_t n,
208
173
  int ht,
209
- size_t * nptr)
210
- {
174
+ size_t* nptr) {
211
175
  const size_t nwords = nbits / 64;
212
176
  size_t i, j, posm = 0;
213
- const uint64_t * bs1 = dbs;
177
+ const uint64_t* bs1 = dbs;
214
178
  for (i = 0; i < n; i++) {
215
- const uint64_t * bs2 = bs1 + 2;
179
+ const uint64_t* bs2 = bs1 + 2;
216
180
  for (j = i + 1; j < n; j++) {
217
181
  /* collect the match only if this satisfies the threshold */
218
- if (hamming <nbits> (bs1, bs2) <= ht)
182
+ if (hamming<nbits>(bs1, bs2) <= ht)
219
183
  posm++;
220
184
  bs2 += nwords;
221
185
  }
@@ -224,185 +188,175 @@ void crosshamming_count_thres (
224
188
  *nptr = posm;
225
189
  }
226
190
 
227
-
228
191
  template <size_t nbits>
229
- size_t match_hamming_thres (
230
- const uint64_t * bs1,
231
- const uint64_t * bs2,
192
+ size_t match_hamming_thres(
193
+ const uint64_t* bs1,
194
+ const uint64_t* bs2,
232
195
  size_t n1,
233
196
  size_t n2,
234
197
  int ht,
235
- int64_t * idx,
236
- hamdis_t * hams)
237
- {
198
+ int64_t* idx,
199
+ hamdis_t* hams) {
238
200
  const size_t nwords = nbits / 64;
239
201
  size_t i, j, posm = 0;
240
202
  hamdis_t h;
241
- const uint64_t * bs2_ = bs2;
203
+ const uint64_t* bs2_ = bs2;
242
204
  for (i = 0; i < n1; i++) {
243
205
  bs2 = bs2_;
244
206
  for (j = 0; j < n2; j++) {
245
207
  /* Here perform the real work of computing the distance */
246
- h = hamming <nbits> (bs1, bs2);
208
+ h = hamming<nbits>(bs1, bs2);
247
209
 
248
210
  /* collect the match only if this satisfies the threshold */
249
211
  if (h <= ht) {
250
212
  /* Enough space to store another match ? */
251
- *idx = i; idx++;
252
- *idx = j; idx++;
213
+ *idx = i;
214
+ idx++;
215
+ *idx = j;
216
+ idx++;
253
217
  *hams = h;
254
218
  hams++;
255
219
  posm++;
256
220
  }
257
- bs2+=nwords; /* next signature */
221
+ bs2 += nwords; /* next signature */
258
222
  }
259
- bs1+=nwords;
223
+ bs1 += nwords;
260
224
  }
261
225
  return posm;
262
226
  }
263
227
 
264
-
265
228
  /* Return closest neighbors w.r.t Hamming distance, using a heap. */
266
229
  template <class HammingComputer>
267
- static
268
- void hammings_knn_hc (
230
+ static void hammings_knn_hc(
269
231
  int bytes_per_code,
270
- int_maxheap_array_t * ha,
271
- const uint8_t * bs1,
272
- const uint8_t * bs2,
232
+ int_maxheap_array_t* ha,
233
+ const uint8_t* bs1,
234
+ const uint8_t* bs2,
273
235
  size_t n2,
274
236
  bool order = true,
275
- bool init_heap = true)
276
- {
237
+ bool init_heap = true) {
277
238
  size_t k = ha->k;
278
- if (init_heap) ha->heapify ();
239
+ if (init_heap)
240
+ ha->heapify();
279
241
 
280
242
  const size_t block_size = hamming_batch_size;
281
243
  for (size_t j0 = 0; j0 < n2; j0 += block_size) {
282
- const size_t j1 = std::min(j0 + block_size, n2);
244
+ const size_t j1 = std::min(j0 + block_size, n2);
283
245
  #pragma omp parallel for
284
- for (int64_t i = 0; i < ha->nh; i++) {
285
- HammingComputer hc (bs1 + i * bytes_per_code, bytes_per_code);
286
-
287
- const uint8_t * bs2_ = bs2 + j0 * bytes_per_code;
288
- hamdis_t dis;
289
- hamdis_t * __restrict bh_val_ = ha->val + i * k;
290
- int64_t * __restrict bh_ids_ = ha->ids + i * k;
291
- size_t j;
292
- for (j = j0; j < j1; j++, bs2_+= bytes_per_code) {
293
- dis = hc.hamming (bs2_);
294
- if (dis < bh_val_[0]) {
295
- faiss::maxheap_replace_top<hamdis_t> (k, bh_val_, bh_ids_, dis, j);
296
- }
246
+ for (int64_t i = 0; i < ha->nh; i++) {
247
+ HammingComputer hc(bs1 + i * bytes_per_code, bytes_per_code);
248
+
249
+ const uint8_t* bs2_ = bs2 + j0 * bytes_per_code;
250
+ hamdis_t dis;
251
+ hamdis_t* __restrict bh_val_ = ha->val + i * k;
252
+ int64_t* __restrict bh_ids_ = ha->ids + i * k;
253
+ size_t j;
254
+ for (j = j0; j < j1; j++, bs2_ += bytes_per_code) {
255
+ dis = hc.hamming(bs2_);
256
+ if (dis < bh_val_[0]) {
257
+ faiss::maxheap_replace_top<hamdis_t>(
258
+ k, bh_val_, bh_ids_, dis, j);
259
+ }
260
+ }
297
261
  }
298
- }
299
262
  }
300
- if (order) ha->reorder ();
301
- }
263
+ if (order)
264
+ ha->reorder();
265
+ }
302
266
 
303
267
  /* Return closest neighbors w.r.t Hamming distance, using max count. */
304
268
  template <class HammingComputer>
305
- static
306
- void hammings_knn_mc (
269
+ static void hammings_knn_mc(
307
270
  int bytes_per_code,
308
- const uint8_t *a,
309
- const uint8_t *b,
271
+ const uint8_t* a,
272
+ const uint8_t* b,
310
273
  size_t na,
311
274
  size_t nb,
312
275
  size_t k,
313
- int32_t *distances,
314
- int64_t *labels)
315
- {
316
- const int nBuckets = bytes_per_code * 8 + 1;
317
- std::vector<int> all_counters(na * nBuckets, 0);
318
- std::unique_ptr<int64_t[]> all_ids_per_dis(new int64_t[na * nBuckets * k]);
319
-
320
- std::vector<HCounterState<HammingComputer>> cs;
321
- for (size_t i = 0; i < na; ++i) {
322
- cs.push_back(HCounterState<HammingComputer>(
323
- all_counters.data() + i * nBuckets,
324
- all_ids_per_dis.get() + i * nBuckets * k,
325
- a + i * bytes_per_code,
326
- 8 * bytes_per_code,
327
- k
328
- ));
329
- }
330
-
331
- const size_t block_size = hamming_batch_size;
332
- for (size_t j0 = 0; j0 < nb; j0 += block_size) {
333
- const size_t j1 = std::min(j0 + block_size, nb);
334
- #pragma omp parallel for
335
- for (int64_t i = 0; i < na; ++i) {
336
- for (size_t j = j0; j < j1; ++j) {
337
- cs[i].update_counter(b + j * bytes_per_code, j);
338
- }
339
- }
340
- }
341
-
342
- for (size_t i = 0; i < na; ++i) {
343
- HCounterState<HammingComputer>& csi = cs[i];
344
-
345
- int nres = 0;
346
- for (int b = 0; b < nBuckets && nres < k; b++) {
347
- for (int l = 0; l < csi.counters[b] && nres < k; l++) {
348
- labels[i * k + nres] = csi.ids_per_dis[b * k + l];
349
- distances[i * k + nres] = b;
350
- nres++;
351
- }
276
+ int32_t* distances,
277
+ int64_t* labels) {
278
+ const int nBuckets = bytes_per_code * 8 + 1;
279
+ std::vector<int> all_counters(na * nBuckets, 0);
280
+ std::unique_ptr<int64_t[]> all_ids_per_dis(new int64_t[na * nBuckets * k]);
281
+
282
+ std::vector<HCounterState<HammingComputer>> cs;
283
+ for (size_t i = 0; i < na; ++i) {
284
+ cs.push_back(HCounterState<HammingComputer>(
285
+ all_counters.data() + i * nBuckets,
286
+ all_ids_per_dis.get() + i * nBuckets * k,
287
+ a + i * bytes_per_code,
288
+ 8 * bytes_per_code,
289
+ k));
352
290
  }
353
- while (nres < k) {
354
- labels[i * k + nres] = -1;
355
- distances[i * k + nres] = std::numeric_limits<int32_t>::max();
356
- ++nres;
291
+
292
+ const size_t block_size = hamming_batch_size;
293
+ for (size_t j0 = 0; j0 < nb; j0 += block_size) {
294
+ const size_t j1 = std::min(j0 + block_size, nb);
295
+ #pragma omp parallel for
296
+ for (int64_t i = 0; i < na; ++i) {
297
+ for (size_t j = j0; j < j1; ++j) {
298
+ cs[i].update_counter(b + j * bytes_per_code, j);
299
+ }
300
+ }
357
301
  }
358
- }
359
- }
360
302
 
303
+ for (size_t i = 0; i < na; ++i) {
304
+ HCounterState<HammingComputer>& csi = cs[i];
361
305
 
306
+ int nres = 0;
307
+ for (int b = 0; b < nBuckets && nres < k; b++) {
308
+ for (int l = 0; l < csi.counters[b] && nres < k; l++) {
309
+ labels[i * k + nres] = csi.ids_per_dis[b * k + l];
310
+ distances[i * k + nres] = b;
311
+ nres++;
312
+ }
313
+ }
314
+ while (nres < k) {
315
+ labels[i * k + nres] = -1;
316
+ distances[i * k + nres] = std::numeric_limits<int32_t>::max();
317
+ ++nres;
318
+ }
319
+ }
320
+ }
362
321
 
363
322
  // works faster than the template version
364
- static
365
- void hammings_knn_hc_1 (
366
- int_maxheap_array_t * ha,
367
- const uint64_t * bs1,
368
- const uint64_t * bs2,
323
+ static void hammings_knn_hc_1(
324
+ int_maxheap_array_t* ha,
325
+ const uint64_t* bs1,
326
+ const uint64_t* bs2,
369
327
  size_t n2,
370
328
  bool order = true,
371
- bool init_heap = true)
372
- {
329
+ bool init_heap = true) {
373
330
  const size_t nwords = 1;
374
331
  size_t k = ha->k;
375
332
 
376
-
377
333
  if (init_heap) {
378
- ha->heapify ();
334
+ ha->heapify();
379
335
  }
380
336
 
381
337
  #pragma omp parallel for
382
338
  for (int64_t i = 0; i < ha->nh; i++) {
383
- const uint64_t bs1_ = bs1 [i];
384
- const uint64_t * bs2_ = bs2;
339
+ const uint64_t bs1_ = bs1[i];
340
+ const uint64_t* bs2_ = bs2;
385
341
  hamdis_t dis;
386
- hamdis_t * bh_val_ = ha->val + i * k;
342
+ hamdis_t* bh_val_ = ha->val + i * k;
387
343
  hamdis_t bh_val_0 = bh_val_[0];
388
- int64_t * bh_ids_ = ha->ids + i * k;
344
+ int64_t* bh_ids_ = ha->ids + i * k;
389
345
  size_t j;
390
- for (j = 0; j < n2; j++, bs2_+= nwords) {
391
- dis = popcount64 (bs1_ ^ *bs2_);
346
+ for (j = 0; j < n2; j++, bs2_ += nwords) {
347
+ dis = popcount64(bs1_ ^ *bs2_);
392
348
  if (dis < bh_val_0) {
393
- faiss::maxheap_replace_top<hamdis_t> (k, bh_val_, bh_ids_, dis, j);
349
+ faiss::maxheap_replace_top<hamdis_t>(
350
+ k, bh_val_, bh_ids_, dis, j);
394
351
  bh_val_0 = bh_val_[0];
395
352
  }
396
353
  }
397
354
  }
398
355
  if (order) {
399
- ha->reorder ();
356
+ ha->reorder();
400
357
  }
401
358
  }
402
359
 
403
-
404
-
405
-
406
360
  /* Functions to maps vectors to bits. Assume proper allocation done beforehand,
407
361
  meaning that b should be be able to receive as many bits as x may produce. */
408
362
 
@@ -410,8 +364,7 @@ void hammings_knn_hc_1 (
410
364
  * dimension 0 corresponds to the least significant bit of b[0], or
411
365
  * equivalently to the lsb of the first byte that is stored.
412
366
  */
413
- void fvec2bitvec (const float * x, uint8_t * b, size_t d)
414
- {
367
+ void fvec2bitvec(const float* x, uint8_t* b, size_t d) {
415
368
  for (int i = 0; i < d; i += 8) {
416
369
  uint8_t w = 0;
417
370
  uint8_t mask = 1;
@@ -426,37 +379,25 @@ void fvec2bitvec (const float * x, uint8_t * b, size_t d)
426
379
  }
427
380
  }
428
381
 
429
-
430
-
431
382
  /* Same but for n vectors.
432
383
  Ensure that the ouptut b is byte-aligned (pad with 0s). */
433
- void fvecs2bitvecs (const float * x, uint8_t * b, size_t d, size_t n)
434
- {
384
+ void fvecs2bitvecs(const float* x, uint8_t* b, size_t d, size_t n) {
435
385
  const int64_t ncodes = ((d + 7) / 8);
436
- #pragma omp parallel for if(n > 100000)
386
+ #pragma omp parallel for if (n > 100000)
437
387
  for (int64_t i = 0; i < n; i++)
438
- fvec2bitvec (x + i * d, b + i * ncodes, d);
388
+ fvec2bitvec(x + i * d, b + i * ncodes, d);
439
389
  }
440
390
 
441
-
442
-
443
- void bitvecs2fvecs (
444
- const uint8_t * b,
445
- float * x,
446
- size_t d,
447
- size_t n) {
448
-
391
+ void bitvecs2fvecs(const uint8_t* b, float* x, size_t d, size_t n) {
449
392
  const int64_t ncodes = ((d + 7) / 8);
450
- #pragma omp parallel for if(n > 100000)
393
+ #pragma omp parallel for if (n > 100000)
451
394
  for (int64_t i = 0; i < n; i++) {
452
- binary_to_real (d, b + i * ncodes, x + i * d);
395
+ binary_to_real(d, b + i * ncodes, x + i * d);
453
396
  }
454
397
  }
455
398
 
456
-
457
399
  /* Reverse bit (NOT a optimized function, only used for print purpose) */
458
- static uint64_t uint64_reverse_bits (uint64_t b)
459
- {
400
+ static uint64_t uint64_reverse_bits(uint64_t b) {
460
401
  int i;
461
402
  uint64_t revb = 0;
462
403
  for (i = 0; i < 64; i++) {
@@ -467,406 +408,371 @@ static uint64_t uint64_reverse_bits (uint64_t b)
467
408
  return revb;
468
409
  }
469
410
 
470
-
471
411
  /* print the bit vector */
472
- void bitvec_print (const uint8_t * b, size_t d)
473
- {
412
+ void bitvec_print(const uint8_t* b, size_t d) {
474
413
  size_t i, j;
475
- for (i = 0; i < d; ) {
476
- uint64_t brev = uint64_reverse_bits (* (uint64_t *) b);
414
+ for (i = 0; i < d;) {
415
+ uint64_t brev = uint64_reverse_bits(*(uint64_t*)b);
477
416
  for (j = 0; j < 64 && i < d; j++, i++) {
478
- printf ("%d", (int) (brev & 1));
417
+ printf("%d", (int)(brev & 1));
479
418
  brev >>= 1;
480
419
  }
481
420
  b += 8;
482
- printf (" ");
421
+ printf(" ");
483
422
  }
484
423
  }
485
424
 
486
-
487
- void bitvec_shuffle (size_t n, size_t da, size_t db,
488
- const int *order,
489
- const uint8_t *a,
490
- uint8_t *b)
491
- {
492
- for(size_t i = 0; i < db; i++) {
493
- FAISS_THROW_IF_NOT (order[i] >= 0 && order[i] < da);
425
+ void bitvec_shuffle(
426
+ size_t n,
427
+ size_t da,
428
+ size_t db,
429
+ const int* order,
430
+ const uint8_t* a,
431
+ uint8_t* b) {
432
+ for (size_t i = 0; i < db; i++) {
433
+ FAISS_THROW_IF_NOT(order[i] >= 0 && order[i] < da);
494
434
  }
495
435
  size_t lda = (da + 7) / 8;
496
436
  size_t ldb = (db + 7) / 8;
497
437
 
498
- #pragma omp parallel for if(n > 10000)
438
+ #pragma omp parallel for if (n > 10000)
499
439
  for (int64_t i = 0; i < n; i++) {
500
- const uint8_t *ai = a + i * lda;
501
- uint8_t *bi = b + i * ldb;
502
- memset (bi, 0, ldb);
503
- for(size_t i = 0; i < db; i++) {
504
- int o = order[i];
440
+ const uint8_t* ai = a + i * lda;
441
+ uint8_t* bi = b + i * ldb;
442
+ memset(bi, 0, ldb);
443
+ for (size_t j = 0; j < db; j++) {
444
+ int o = order[j];
505
445
  uint8_t the_bit = (ai[o >> 3] >> (o & 7)) & 1;
506
- bi[i >> 3] |= the_bit << (i & 7);
446
+ bi[j >> 3] |= the_bit << (j & 7);
507
447
  }
508
448
  }
509
-
510
449
  }
511
450
 
512
-
513
-
514
451
  /*----------------------------------------*/
515
452
  /* Hamming distance computation and k-nn */
516
453
 
517
-
518
- #define C64(x) ((uint64_t *)x)
519
-
454
+ #define C64(x) ((uint64_t*)x)
520
455
 
521
456
  /* Compute a set of Hamming distances */
522
- void hammings (
523
- const uint8_t * a,
524
- const uint8_t * b,
525
- size_t na, size_t nb,
457
+ void hammings(
458
+ const uint8_t* a,
459
+ const uint8_t* b,
460
+ size_t na,
461
+ size_t nb,
526
462
  size_t ncodes,
527
- hamdis_t * __restrict dis)
528
- {
529
- FAISS_THROW_IF_NOT (ncodes % 8 == 0);
463
+ hamdis_t* __restrict dis) {
464
+ FAISS_THROW_IF_NOT(ncodes % 8 == 0);
530
465
  switch (ncodes) {
531
466
  case 8:
532
- faiss::hammings <64> (C64(a), C64(b), na, nb, dis); return;
467
+ faiss::hammings<64>(C64(a), C64(b), na, nb, dis);
468
+ return;
533
469
  case 16:
534
- faiss::hammings <128> (C64(a), C64(b), na, nb, dis); return;
470
+ faiss::hammings<128>(C64(a), C64(b), na, nb, dis);
471
+ return;
535
472
  case 32:
536
- faiss::hammings <256> (C64(a), C64(b), na, nb, dis); return;
473
+ faiss::hammings<256>(C64(a), C64(b), na, nb, dis);
474
+ return;
537
475
  case 64:
538
- faiss::hammings <512> (C64(a), C64(b), na, nb, dis); return;
476
+ faiss::hammings<512>(C64(a), C64(b), na, nb, dis);
477
+ return;
539
478
  default:
540
- faiss::hammings (C64(a), C64(b), na, nb, ncodes * 8, dis); return;
479
+ faiss::hammings(C64(a), C64(b), na, nb, ncodes * 8, dis);
480
+ return;
541
481
  }
542
482
  }
543
483
 
544
484
  void hammings_knn(
545
- int_maxheap_array_t *ha,
546
- const uint8_t *a,
547
- const uint8_t *b,
548
- size_t nb,
549
- size_t ncodes,
550
- int order)
551
- {
485
+ int_maxheap_array_t* ha,
486
+ const uint8_t* a,
487
+ const uint8_t* b,
488
+ size_t nb,
489
+ size_t ncodes,
490
+ int order) {
552
491
  hammings_knn_hc(ha, a, b, nb, ncodes, order);
553
492
  }
554
493
 
555
- void hammings_knn_hc (
556
- int_maxheap_array_t * ha,
557
- const uint8_t * a,
558
- const uint8_t * b,
494
+ void hammings_knn_hc(
495
+ int_maxheap_array_t* ha,
496
+ const uint8_t* a,
497
+ const uint8_t* b,
559
498
  size_t nb,
560
499
  size_t ncodes,
561
- int order)
562
- {
500
+ int order) {
563
501
  switch (ncodes) {
564
- case 4:
565
- hammings_knn_hc<faiss::HammingComputer4>
566
- (4, ha, a, b, nb, order, true);
567
- break;
568
- case 8:
569
- hammings_knn_hc_1 (ha, C64(a), C64(b), nb, order, true);
570
- // hammings_knn_hc<faiss::HammingComputer8>
571
- // (8, ha, a, b, nb, order, true);
572
- break;
573
- case 16:
574
- hammings_knn_hc<faiss::HammingComputer16>
575
- (16, ha, a, b, nb, order, true);
576
- break;
577
- case 32:
578
- hammings_knn_hc<faiss::HammingComputer32>
579
- (32, ha, a, b, nb, order, true);
580
- break;
581
- default:
582
- if(ncodes % 8 == 0) {
583
- hammings_knn_hc<faiss::HammingComputerM8>
584
- (ncodes, ha, a, b, nb, order, true);
585
- } else {
586
- hammings_knn_hc<faiss::HammingComputerDefault>
587
- (ncodes, ha, a, b, nb, order, true);
588
-
589
- }
502
+ case 4:
503
+ hammings_knn_hc<faiss::HammingComputer4>(
504
+ 4, ha, a, b, nb, order, true);
505
+ break;
506
+ case 8:
507
+ hammings_knn_hc_1(ha, C64(a), C64(b), nb, order, true);
508
+ // hammings_knn_hc<faiss::HammingComputer8>
509
+ // (8, ha, a, b, nb, order, true);
510
+ break;
511
+ case 16:
512
+ hammings_knn_hc<faiss::HammingComputer16>(
513
+ 16, ha, a, b, nb, order, true);
514
+ break;
515
+ case 32:
516
+ hammings_knn_hc<faiss::HammingComputer32>(
517
+ 32, ha, a, b, nb, order, true);
518
+ break;
519
+ default:
520
+ hammings_knn_hc<faiss::HammingComputerDefault>(
521
+ ncodes, ha, a, b, nb, order, true);
522
+ break;
590
523
  }
591
524
  }
592
525
 
593
526
  void hammings_knn_mc(
594
- const uint8_t * a,
595
- const uint8_t * b,
596
- size_t na,
597
- size_t nb,
598
- size_t k,
599
- size_t ncodes,
600
- int32_t *distances,
601
- int64_t *labels)
602
- {
527
+ const uint8_t* a,
528
+ const uint8_t* b,
529
+ size_t na,
530
+ size_t nb,
531
+ size_t k,
532
+ size_t ncodes,
533
+ int32_t* distances,
534
+ int64_t* labels) {
603
535
  switch (ncodes) {
604
- case 4:
605
- hammings_knn_mc<faiss::HammingComputer4>(
606
- 4, a, b, na, nb, k, distances, labels
607
- );
608
- break;
609
- case 8:
610
- // TODO(hoss): Write analog to hammings_knn_hc_1
611
- // hammings_knn_hc_1 (ha, C64(a), C64(b), nb, order, true);
612
- hammings_knn_mc<faiss::HammingComputer8>(
613
- 8, a, b, na, nb, k, distances, labels
614
- );
615
- break;
616
- case 16:
617
- hammings_knn_mc<faiss::HammingComputer16>(
618
- 16, a, b, na, nb, k, distances, labels
619
- );
620
- break;
621
- case 32:
622
- hammings_knn_mc<faiss::HammingComputer32>(
623
- 32, a, b, na, nb, k, distances, labels
624
- );
625
- break;
626
- default:
627
- if(ncodes % 8 == 0) {
628
- hammings_knn_mc<faiss::HammingComputerM8>(
629
- ncodes, a, b, na, nb, k, distances, labels
630
- );
631
- } else {
536
+ case 4:
537
+ hammings_knn_mc<faiss::HammingComputer4>(
538
+ 4, a, b, na, nb, k, distances, labels);
539
+ break;
540
+ case 8:
541
+ // TODO(hoss): Write analog to hammings_knn_hc_1
542
+ // hammings_knn_hc_1 (ha, C64(a), C64(b), nb, order, true);
543
+ hammings_knn_mc<faiss::HammingComputer8>(
544
+ 8, a, b, na, nb, k, distances, labels);
545
+ break;
546
+ case 16:
547
+ hammings_knn_mc<faiss::HammingComputer16>(
548
+ 16, a, b, na, nb, k, distances, labels);
549
+ break;
550
+ case 32:
551
+ hammings_knn_mc<faiss::HammingComputer32>(
552
+ 32, a, b, na, nb, k, distances, labels);
553
+ break;
554
+ default:
632
555
  hammings_knn_mc<faiss::HammingComputerDefault>(
633
- ncodes, a, b, na, nb, k, distances, labels
634
- );
635
- }
556
+ ncodes, a, b, na, nb, k, distances, labels);
557
+ break;
636
558
  }
637
559
  }
638
560
  template <class HammingComputer>
639
- static
640
- void hamming_range_search_template (
641
- const uint8_t * a,
642
- const uint8_t * b,
643
- size_t na,
644
- size_t nb,
645
- int radius,
646
- size_t code_size,
647
- RangeSearchResult *res)
648
- {
649
-
561
+ static void hamming_range_search_template(
562
+ const uint8_t* a,
563
+ const uint8_t* b,
564
+ size_t na,
565
+ size_t nb,
566
+ int radius,
567
+ size_t code_size,
568
+ RangeSearchResult* res) {
650
569
  #pragma omp parallel
651
570
  {
652
- RangeSearchPartialResult pres (res);
571
+ RangeSearchPartialResult pres(res);
653
572
 
654
573
  #pragma omp for
655
574
  for (int64_t i = 0; i < na; i++) {
656
- HammingComputer hc (a + i * code_size, code_size);
657
- const uint8_t * yi = b;
658
- RangeQueryResult & qres = pres.new_result (i);
575
+ HammingComputer hc(a + i * code_size, code_size);
576
+ const uint8_t* yi = b;
577
+ RangeQueryResult& qres = pres.new_result(i);
659
578
 
660
579
  for (size_t j = 0; j < nb; j++) {
661
- int dis = hc.hamming (yi);
580
+ int dis = hc.hamming(yi);
662
581
  if (dis < radius) {
663
582
  qres.add(dis, j);
664
583
  }
665
584
  yi += code_size;
666
585
  }
667
586
  }
668
- pres.finalize ();
587
+ pres.finalize();
669
588
  }
670
589
  }
671
590
 
672
- void hamming_range_search (
673
- const uint8_t * a,
674
- const uint8_t * b,
675
- size_t na,
676
- size_t nb,
677
- int radius,
678
- size_t code_size,
679
- RangeSearchResult *result)
680
- {
591
+ void hamming_range_search(
592
+ const uint8_t* a,
593
+ const uint8_t* b,
594
+ size_t na,
595
+ size_t nb,
596
+ int radius,
597
+ size_t code_size,
598
+ RangeSearchResult* result) {
599
+ #define HC(name) \
600
+ hamming_range_search_template<name>(a, b, na, nb, radius, code_size, result)
681
601
 
682
- #define HC(name) hamming_range_search_template<name> (a, b, na, nb, radius, code_size, result)
683
-
684
- switch(code_size) {
685
- case 4: HC(HammingComputer4); break;
686
- case 8: HC(HammingComputer8); break;
687
- case 16: HC(HammingComputer16); break;
688
- case 32: HC(HammingComputer32); break;
689
- default:
690
- if (code_size % 8 == 0) {
691
- HC(HammingComputerM8);
692
- } else {
602
+ switch (code_size) {
603
+ case 4:
604
+ HC(HammingComputer4);
605
+ break;
606
+ case 8:
607
+ HC(HammingComputer8);
608
+ break;
609
+ case 16:
610
+ HC(HammingComputer16);
611
+ break;
612
+ case 32:
613
+ HC(HammingComputer32);
614
+ break;
615
+ default:
693
616
  HC(HammingComputerDefault);
694
- }
617
+ break;
695
618
  }
696
619
  #undef HC
697
620
  }
698
621
 
699
-
700
-
701
622
  /* Count number of matches given a max threshold */
702
- void hamming_count_thres (
703
- const uint8_t * bs1,
704
- const uint8_t * bs2,
623
+ void hamming_count_thres(
624
+ const uint8_t* bs1,
625
+ const uint8_t* bs2,
705
626
  size_t n1,
706
627
  size_t n2,
707
628
  hamdis_t ht,
708
629
  size_t ncodes,
709
- size_t * nptr)
710
- {
630
+ size_t* nptr) {
711
631
  switch (ncodes) {
712
632
  case 8:
713
- faiss::hamming_count_thres <64> (C64(bs1), C64(bs2),
714
- n1, n2, ht, nptr);
633
+ faiss::hamming_count_thres<64>(
634
+ C64(bs1), C64(bs2), n1, n2, ht, nptr);
715
635
  return;
716
636
  case 16:
717
- faiss::hamming_count_thres <128> (C64(bs1), C64(bs2),
718
- n1, n2, ht, nptr);
637
+ faiss::hamming_count_thres<128>(
638
+ C64(bs1), C64(bs2), n1, n2, ht, nptr);
719
639
  return;
720
640
  case 32:
721
- faiss::hamming_count_thres <256> (C64(bs1), C64(bs2),
722
- n1, n2, ht, nptr);
641
+ faiss::hamming_count_thres<256>(
642
+ C64(bs1), C64(bs2), n1, n2, ht, nptr);
723
643
  return;
724
644
  case 64:
725
- faiss::hamming_count_thres <512> (C64(bs1), C64(bs2),
726
- n1, n2, ht, nptr);
645
+ faiss::hamming_count_thres<512>(
646
+ C64(bs1), C64(bs2), n1, n2, ht, nptr);
727
647
  return;
728
648
  default:
729
- FAISS_THROW_FMT ("not implemented for %zu bits", ncodes);
649
+ FAISS_THROW_FMT("not implemented for %zu bits", ncodes);
730
650
  }
731
651
  }
732
652
 
733
-
734
653
  /* Count number of cross-matches given a threshold */
735
- void crosshamming_count_thres (
736
- const uint8_t * dbs,
654
+ void crosshamming_count_thres(
655
+ const uint8_t* dbs,
737
656
  size_t n,
738
657
  hamdis_t ht,
739
658
  size_t ncodes,
740
- size_t * nptr)
741
- {
659
+ size_t* nptr) {
742
660
  switch (ncodes) {
743
661
  case 8:
744
- faiss::crosshamming_count_thres <64> (C64(dbs), n, ht, nptr);
662
+ faiss::crosshamming_count_thres<64>(C64(dbs), n, ht, nptr);
745
663
  return;
746
664
  case 16:
747
- faiss::crosshamming_count_thres <128> (C64(dbs), n, ht, nptr);
665
+ faiss::crosshamming_count_thres<128>(C64(dbs), n, ht, nptr);
748
666
  return;
749
667
  case 32:
750
- faiss::crosshamming_count_thres <256> (C64(dbs), n, ht, nptr);
668
+ faiss::crosshamming_count_thres<256>(C64(dbs), n, ht, nptr);
751
669
  return;
752
670
  case 64:
753
- faiss::crosshamming_count_thres <512> (C64(dbs), n, ht, nptr);
671
+ faiss::crosshamming_count_thres<512>(C64(dbs), n, ht, nptr);
754
672
  return;
755
673
  default:
756
- FAISS_THROW_FMT ("not implemented for %zu bits", ncodes);
674
+ FAISS_THROW_FMT("not implemented for %zu bits", ncodes);
757
675
  }
758
676
  }
759
677
 
760
-
761
678
  /* Returns all matches given a threshold */
762
- size_t match_hamming_thres (
763
- const uint8_t * bs1,
764
- const uint8_t * bs2,
679
+ size_t match_hamming_thres(
680
+ const uint8_t* bs1,
681
+ const uint8_t* bs2,
765
682
  size_t n1,
766
683
  size_t n2,
767
684
  hamdis_t ht,
768
685
  size_t ncodes,
769
- int64_t * idx,
770
- hamdis_t * dis)
771
- {
686
+ int64_t* idx,
687
+ hamdis_t* dis) {
772
688
  switch (ncodes) {
773
689
  case 8:
774
- return faiss::match_hamming_thres <64> (C64(bs1), C64(bs2),
775
- n1, n2, ht, idx, dis);
690
+ return faiss::match_hamming_thres<64>(
691
+ C64(bs1), C64(bs2), n1, n2, ht, idx, dis);
776
692
  case 16:
777
- return faiss::match_hamming_thres <128> (C64(bs1), C64(bs2),
778
- n1, n2, ht, idx, dis);
693
+ return faiss::match_hamming_thres<128>(
694
+ C64(bs1), C64(bs2), n1, n2, ht, idx, dis);
779
695
  case 32:
780
- return faiss::match_hamming_thres <256> (C64(bs1), C64(bs2),
781
- n1, n2, ht, idx, dis);
696
+ return faiss::match_hamming_thres<256>(
697
+ C64(bs1), C64(bs2), n1, n2, ht, idx, dis);
782
698
  case 64:
783
- return faiss::match_hamming_thres <512> (C64(bs1), C64(bs2),
784
- n1, n2, ht, idx, dis);
699
+ return faiss::match_hamming_thres<512>(
700
+ C64(bs1), C64(bs2), n1, n2, ht, idx, dis);
785
701
  default:
786
- FAISS_THROW_FMT ("not implemented for %zu bits", ncodes);
702
+ FAISS_THROW_FMT("not implemented for %zu bits", ncodes);
787
703
  return 0;
788
704
  }
789
705
  }
790
706
 
791
-
792
707
  #undef C64
793
708
 
794
-
795
-
796
709
  /*************************************
797
710
  * generalized Hamming distances
798
711
  ************************************/
799
712
 
800
-
801
-
802
713
  template <class HammingComputer>
803
- static void hamming_dis_inner_loop (
804
- const uint8_t *ca,
805
- const uint8_t *cb,
714
+ static void hamming_dis_inner_loop(
715
+ const uint8_t* ca,
716
+ const uint8_t* cb,
806
717
  size_t nb,
807
718
  size_t code_size,
808
719
  int k,
809
- hamdis_t * bh_val_,
810
- int64_t * bh_ids_)
811
- {
812
-
813
- HammingComputer hc (ca, code_size);
720
+ hamdis_t* bh_val_,
721
+ int64_t* bh_ids_) {
722
+ HammingComputer hc(ca, code_size);
814
723
 
815
724
  for (size_t j = 0; j < nb; j++) {
816
- int ndiff = hc.hamming (cb);
725
+ int ndiff = hc.hamming(cb);
817
726
  cb += code_size;
818
727
  if (ndiff < bh_val_[0]) {
819
- maxheap_replace_top<hamdis_t> (k, bh_val_, bh_ids_, ndiff, j);
728
+ maxheap_replace_top<hamdis_t>(k, bh_val_, bh_ids_, ndiff, j);
820
729
  }
821
730
  }
822
731
  }
823
732
 
824
- void generalized_hammings_knn_hc (
825
- int_maxheap_array_t * ha,
826
- const uint8_t * a,
827
- const uint8_t * b,
733
+ void generalized_hammings_knn_hc(
734
+ int_maxheap_array_t* ha,
735
+ const uint8_t* a,
736
+ const uint8_t* b,
828
737
  size_t nb,
829
738
  size_t code_size,
830
- int ordered)
831
- {
739
+ int ordered) {
832
740
  int na = ha->nh;
833
741
  int k = ha->k;
834
742
 
835
743
  if (ordered)
836
- ha->heapify ();
744
+ ha->heapify();
837
745
 
838
746
  #pragma omp parallel for
839
747
  for (int i = 0; i < na; i++) {
840
- const uint8_t *ca = a + i * code_size;
841
- const uint8_t *cb = b;
748
+ const uint8_t* ca = a + i * code_size;
749
+ const uint8_t* cb = b;
842
750
 
843
- hamdis_t * bh_val_ = ha->val + i * k;
844
- int64_t * bh_ids_ = ha->ids + i * k;
751
+ hamdis_t* bh_val_ = ha->val + i * k;
752
+ int64_t* bh_ids_ = ha->ids + i * k;
845
753
 
846
754
  switch (code_size) {
847
- case 8:
848
- hamming_dis_inner_loop<GenHammingComputer8>
849
- (ca, cb, nb, 8, k, bh_val_, bh_ids_);
850
- break;
851
- case 16:
852
- hamming_dis_inner_loop<GenHammingComputer16>
853
- (ca, cb, nb, 16, k, bh_val_, bh_ids_);
854
- break;
855
- case 32:
856
- hamming_dis_inner_loop<GenHammingComputer32>
857
- (ca, cb, nb, 32, k, bh_val_, bh_ids_);
858
- break;
859
- default:
860
- hamming_dis_inner_loop<GenHammingComputerM8>
861
- (ca, cb, nb, code_size, k, bh_val_, bh_ids_);
862
- break;
755
+ case 8:
756
+ hamming_dis_inner_loop<GenHammingComputer8>(
757
+ ca, cb, nb, 8, k, bh_val_, bh_ids_);
758
+ break;
759
+ case 16:
760
+ hamming_dis_inner_loop<GenHammingComputer16>(
761
+ ca, cb, nb, 16, k, bh_val_, bh_ids_);
762
+ break;
763
+ case 32:
764
+ hamming_dis_inner_loop<GenHammingComputer32>(
765
+ ca, cb, nb, 32, k, bh_val_, bh_ids_);
766
+ break;
767
+ default:
768
+ hamming_dis_inner_loop<GenHammingComputerM8>(
769
+ ca, cb, nb, code_size, k, bh_val_, bh_ids_);
770
+ break;
863
771
  }
864
772
  }
865
773
 
866
774
  if (ordered)
867
- ha->reorder ();
868
-
775
+ ha->reorder();
869
776
  }
870
777
 
871
-
872
778
  } // namespace faiss