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