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
@@ -7,15 +7,15 @@
7
7
 
8
8
  namespace faiss {
9
9
 
10
+ extern const uint8_t hamdis_tab_ham_bytes[256];
10
11
 
11
- inline BitstringWriter::BitstringWriter(uint8_t *code, size_t code_size):
12
- code (code), code_size (code_size), i(0)
13
- {
14
- memset (code, 0, code_size);
12
+ inline BitstringWriter::BitstringWriter(uint8_t* code, size_t code_size)
13
+ : code(code), code_size(code_size), i(0) {
14
+ memset(code, 0, code_size);
15
15
  }
16
16
 
17
17
  inline void BitstringWriter::write(uint64_t x, int nbit) {
18
- assert (code_size * 8 >= nbit + i);
18
+ assert(code_size * 8 >= nbit + i);
19
19
  // nb of available bits in i / 8
20
20
  int na = 8 - (i & 7);
21
21
 
@@ -35,13 +35,11 @@ inline void BitstringWriter::write(uint64_t x, int nbit) {
35
35
  }
36
36
  }
37
37
 
38
-
39
- inline BitstringReader::BitstringReader(const uint8_t *code, size_t code_size):
40
- code (code), code_size (code_size), i(0)
41
- {}
38
+ inline BitstringReader::BitstringReader(const uint8_t* code, size_t code_size)
39
+ : code(code), code_size(code_size), i(0) {}
42
40
 
43
41
  inline uint64_t BitstringReader::read(int nbit) {
44
- assert (code_size * 8 >= nbit + i);
42
+ assert(code_size * 8 >= nbit + i);
45
43
  // nb of available bits in i / 8
46
44
  int na = 8 - (i & 7);
47
45
  // get available bits in current byte
@@ -67,7 +65,6 @@ inline uint64_t BitstringReader::read(int nbit) {
67
65
  }
68
66
  }
69
67
 
70
-
71
68
  /******************************************************************
72
69
  * The HammingComputer series of classes compares a single code of
73
70
  * size 4 to 32 to incoming codes. They are intended for use as a
@@ -76,68 +73,64 @@ inline uint64_t BitstringReader::read(int nbit) {
76
73
  * hamming() functions and put the a0, a1, ... in registers.
77
74
  ******************************************************************/
78
75
 
79
-
80
76
  struct HammingComputer4 {
81
77
  uint32_t a0;
82
78
 
83
- HammingComputer4 () {}
79
+ HammingComputer4() {}
84
80
 
85
- HammingComputer4 (const uint8_t *a, int code_size) {
86
- set (a, code_size);
81
+ HammingComputer4(const uint8_t* a, int code_size) {
82
+ set(a, code_size);
87
83
  }
88
84
 
89
- void set (const uint8_t *a, int code_size) {
90
- assert (code_size == 4);
91
- a0 = *(uint32_t *)a;
85
+ void set(const uint8_t* a, int code_size) {
86
+ assert(code_size == 4);
87
+ a0 = *(uint32_t*)a;
92
88
  }
93
89
 
94
- inline int hamming (const uint8_t *b) const {
95
- return popcount64 (*(uint32_t *)b ^ a0);
90
+ inline int hamming(const uint8_t* b) const {
91
+ return popcount64(*(uint32_t*)b ^ a0);
96
92
  }
97
-
98
93
  };
99
94
 
100
95
  struct HammingComputer8 {
101
96
  uint64_t a0;
102
97
 
103
- HammingComputer8 () {}
98
+ HammingComputer8() {}
104
99
 
105
- HammingComputer8 (const uint8_t *a, int code_size) {
106
- set (a, code_size);
100
+ HammingComputer8(const uint8_t* a, int code_size) {
101
+ set(a, code_size);
107
102
  }
108
103
 
109
- void set (const uint8_t *a, int code_size) {
110
- assert (code_size == 8);
111
- a0 = *(uint64_t *)a;
104
+ void set(const uint8_t* a, int code_size) {
105
+ assert(code_size == 8);
106
+ a0 = *(uint64_t*)a;
112
107
  }
113
108
 
114
- inline int hamming (const uint8_t *b) const {
115
- return popcount64 (*(uint64_t *)b ^ a0);
109
+ inline int hamming(const uint8_t* b) const {
110
+ return popcount64(*(uint64_t*)b ^ a0);
116
111
  }
117
-
118
112
  };
119
113
 
120
-
121
114
  struct HammingComputer16 {
122
115
  uint64_t a0, a1;
123
116
 
124
- HammingComputer16 () {}
117
+ HammingComputer16() {}
125
118
 
126
- HammingComputer16 (const uint8_t *a8, int code_size) {
127
- set (a8, code_size);
119
+ HammingComputer16(const uint8_t* a8, int code_size) {
120
+ set(a8, code_size);
128
121
  }
129
122
 
130
- void set (const uint8_t *a8, int code_size) {
131
- assert (code_size == 16);
132
- const uint64_t *a = (uint64_t *)a8;
133
- a0 = a[0]; a1 = a[1];
123
+ void set(const uint8_t* a8, int code_size) {
124
+ assert(code_size == 16);
125
+ const uint64_t* a = (uint64_t*)a8;
126
+ a0 = a[0];
127
+ a1 = a[1];
134
128
  }
135
129
 
136
- inline int hamming (const uint8_t *b8) const {
137
- const uint64_t *b = (uint64_t *)b8;
138
- return popcount64 (b[0] ^ a0) + popcount64 (b[1] ^ a1);
130
+ inline int hamming(const uint8_t* b8) const {
131
+ const uint64_t* b = (uint64_t*)b8;
132
+ return popcount64(b[0] ^ a0) + popcount64(b[1] ^ a1);
139
133
  }
140
-
141
134
  };
142
135
 
143
136
  // when applied to an array, 1/2 of the 64-bit accesses are unaligned.
@@ -146,150 +139,212 @@ struct HammingComputer20 {
146
139
  uint64_t a0, a1;
147
140
  uint32_t a2;
148
141
 
149
- HammingComputer20 () {}
142
+ HammingComputer20() {}
150
143
 
151
- HammingComputer20 (const uint8_t *a8, int code_size) {
152
- set (a8, code_size);
144
+ HammingComputer20(const uint8_t* a8, int code_size) {
145
+ set(a8, code_size);
153
146
  }
154
147
 
155
- void set (const uint8_t *a8, int code_size) {
156
- assert (code_size == 20);
157
- const uint64_t *a = (uint64_t *)a8;
158
- a0 = a[0]; a1 = a[1]; a2 = a[2];
148
+ void set(const uint8_t* a8, int code_size) {
149
+ assert(code_size == 20);
150
+ const uint64_t* a = (uint64_t*)a8;
151
+ a0 = a[0];
152
+ a1 = a[1];
153
+ a2 = a[2];
159
154
  }
160
155
 
161
- inline int hamming (const uint8_t *b8) const {
162
- const uint64_t *b = (uint64_t *)b8;
163
- return popcount64 (b[0] ^ a0) + popcount64 (b[1] ^ a1) +
164
- popcount64 (*(uint32_t*)(b + 2) ^ a2);
156
+ inline int hamming(const uint8_t* b8) const {
157
+ const uint64_t* b = (uint64_t*)b8;
158
+ return popcount64(b[0] ^ a0) + popcount64(b[1] ^ a1) +
159
+ popcount64(*(uint32_t*)(b + 2) ^ a2);
165
160
  }
166
161
  };
167
162
 
168
163
  struct HammingComputer32 {
169
164
  uint64_t a0, a1, a2, a3;
170
165
 
171
- HammingComputer32 () {}
166
+ HammingComputer32() {}
172
167
 
173
- HammingComputer32 (const uint8_t *a8, int code_size) {
174
- set (a8, code_size);
168
+ HammingComputer32(const uint8_t* a8, int code_size) {
169
+ set(a8, code_size);
175
170
  }
176
171
 
177
- void set (const uint8_t *a8, int code_size) {
178
- assert (code_size == 32);
179
- const uint64_t *a = (uint64_t *)a8;
180
- a0 = a[0]; a1 = a[1]; a2 = a[2]; a3 = a[3];
172
+ void set(const uint8_t* a8, int code_size) {
173
+ assert(code_size == 32);
174
+ const uint64_t* a = (uint64_t*)a8;
175
+ a0 = a[0];
176
+ a1 = a[1];
177
+ a2 = a[2];
178
+ a3 = a[3];
181
179
  }
182
180
 
183
- inline int hamming (const uint8_t *b8) const {
184
- const uint64_t *b = (uint64_t *)b8;
185
- return popcount64 (b[0] ^ a0) + popcount64 (b[1] ^ a1) +
186
- popcount64 (b[2] ^ a2) + popcount64 (b[3] ^ a3);
181
+ inline int hamming(const uint8_t* b8) const {
182
+ const uint64_t* b = (uint64_t*)b8;
183
+ return popcount64(b[0] ^ a0) + popcount64(b[1] ^ a1) +
184
+ popcount64(b[2] ^ a2) + popcount64(b[3] ^ a3);
187
185
  }
188
-
189
186
  };
190
187
 
191
188
  struct HammingComputer64 {
192
189
  uint64_t a0, a1, a2, a3, a4, a5, a6, a7;
193
190
 
194
- HammingComputer64 () {}
191
+ HammingComputer64() {}
195
192
 
196
- HammingComputer64 (const uint8_t *a8, int code_size) {
197
- set (a8, code_size);
193
+ HammingComputer64(const uint8_t* a8, int code_size) {
194
+ set(a8, code_size);
198
195
  }
199
196
 
200
- void set (const uint8_t *a8, int code_size) {
201
- assert (code_size == 64);
202
- const uint64_t *a = (uint64_t *)a8;
203
- a0 = a[0]; a1 = a[1]; a2 = a[2]; a3 = a[3];
204
- a4 = a[4]; a5 = a[5]; a6 = a[6]; a7 = a[7];
197
+ void set(const uint8_t* a8, int code_size) {
198
+ assert(code_size == 64);
199
+ const uint64_t* a = (uint64_t*)a8;
200
+ a0 = a[0];
201
+ a1 = a[1];
202
+ a2 = a[2];
203
+ a3 = a[3];
204
+ a4 = a[4];
205
+ a5 = a[5];
206
+ a6 = a[6];
207
+ a7 = a[7];
205
208
  }
206
209
 
207
- inline int hamming (const uint8_t *b8) const {
208
- const uint64_t *b = (uint64_t *)b8;
209
- return popcount64 (b[0] ^ a0) + popcount64 (b[1] ^ a1) +
210
- popcount64 (b[2] ^ a2) + popcount64 (b[3] ^ a3) +
211
- popcount64 (b[4] ^ a4) + popcount64 (b[5] ^ a5) +
212
- popcount64 (b[6] ^ a6) + popcount64 (b[7] ^ a7);
210
+ inline int hamming(const uint8_t* b8) const {
211
+ const uint64_t* b = (uint64_t*)b8;
212
+ return popcount64(b[0] ^ a0) + popcount64(b[1] ^ a1) +
213
+ popcount64(b[2] ^ a2) + popcount64(b[3] ^ a3) +
214
+ popcount64(b[4] ^ a4) + popcount64(b[5] ^ a5) +
215
+ popcount64(b[6] ^ a6) + popcount64(b[7] ^ a7);
213
216
  }
214
-
215
217
  };
216
218
 
217
- // very inefficient...
218
219
  struct HammingComputerDefault {
219
- const uint8_t *a;
220
- int n;
220
+ const uint8_t* a8;
221
+ int quotient8;
222
+ int remainder8;
221
223
 
222
- HammingComputerDefault () {}
224
+ HammingComputerDefault() {}
223
225
 
224
- HammingComputerDefault (const uint8_t *a8, int code_size) {
225
- set (a8, code_size);
226
+ HammingComputerDefault(const uint8_t* a8, int code_size) {
227
+ set(a8, code_size);
226
228
  }
227
229
 
228
- void set (const uint8_t *a8, int code_size) {
229
- a = a8;
230
- n = code_size;
230
+ void set(const uint8_t* a8, int code_size) {
231
+ this->a8 = a8;
232
+ quotient8 = code_size / 8;
233
+ remainder8 = code_size % 8;
231
234
  }
232
235
 
233
- int hamming (const uint8_t *b8) const {
236
+ int hamming(const uint8_t* b8) const {
234
237
  int accu = 0;
235
- for (int i = 0; i < n; i++)
236
- accu += popcount64 (a[i] ^ b8[i]);
238
+
239
+ const uint64_t* a64 = reinterpret_cast<const uint64_t*>(a8);
240
+ const uint64_t* b64 = reinterpret_cast<const uint64_t*>(b8);
241
+ int i = 0, len = quotient8;
242
+ switch (len & 7) {
243
+ default:
244
+ while (len > 7) {
245
+ len -= 8;
246
+ accu += popcount64(a64[i] ^ b64[i]);
247
+ i++;
248
+ case 7:
249
+ accu += popcount64(a64[i] ^ b64[i]);
250
+ i++;
251
+ case 6:
252
+ accu += popcount64(a64[i] ^ b64[i]);
253
+ i++;
254
+ case 5:
255
+ accu += popcount64(a64[i] ^ b64[i]);
256
+ i++;
257
+ case 4:
258
+ accu += popcount64(a64[i] ^ b64[i]);
259
+ i++;
260
+ case 3:
261
+ accu += popcount64(a64[i] ^ b64[i]);
262
+ i++;
263
+ case 2:
264
+ accu += popcount64(a64[i] ^ b64[i]);
265
+ i++;
266
+ case 1:
267
+ accu += popcount64(a64[i] ^ b64[i]);
268
+ i++;
269
+ }
270
+ }
271
+ if (remainder8) {
272
+ const uint8_t* a = a8 + 8 * quotient8;
273
+ const uint8_t* b = b8 + 8 * quotient8;
274
+ switch (remainder8) {
275
+ case 7:
276
+ accu += hamdis_tab_ham_bytes[a[6] ^ b[6]];
277
+ case 6:
278
+ accu += hamdis_tab_ham_bytes[a[5] ^ b[5]];
279
+ case 5:
280
+ accu += hamdis_tab_ham_bytes[a[4] ^ b[4]];
281
+ case 4:
282
+ accu += hamdis_tab_ham_bytes[a[3] ^ b[3]];
283
+ case 3:
284
+ accu += hamdis_tab_ham_bytes[a[2] ^ b[2]];
285
+ case 2:
286
+ accu += hamdis_tab_ham_bytes[a[1] ^ b[1]];
287
+ case 1:
288
+ accu += hamdis_tab_ham_bytes[a[0] ^ b[0]];
289
+ default:
290
+ break;
291
+ }
292
+ }
293
+
237
294
  return accu;
238
295
  }
239
-
240
296
  };
241
297
 
298
+ // more inefficient than HammingComputerDefault (obsolete)
242
299
  struct HammingComputerM8 {
243
- const uint64_t *a;
300
+ const uint64_t* a;
244
301
  int n;
245
302
 
246
- HammingComputerM8 () {}
303
+ HammingComputerM8() {}
247
304
 
248
- HammingComputerM8 (const uint8_t *a8, int code_size) {
249
- set (a8, code_size);
305
+ HammingComputerM8(const uint8_t* a8, int code_size) {
306
+ set(a8, code_size);
250
307
  }
251
308
 
252
- void set (const uint8_t *a8, int code_size) {
253
- assert (code_size % 8 == 0);
254
- a = (uint64_t *)a8;
309
+ void set(const uint8_t* a8, int code_size) {
310
+ assert(code_size % 8 == 0);
311
+ a = (uint64_t*)a8;
255
312
  n = code_size / 8;
256
313
  }
257
314
 
258
- int hamming (const uint8_t *b8) const {
259
- const uint64_t *b = (uint64_t *)b8;
315
+ int hamming(const uint8_t* b8) const {
316
+ const uint64_t* b = (uint64_t*)b8;
260
317
  int accu = 0;
261
318
  for (int i = 0; i < n; i++)
262
- accu += popcount64 (a[i] ^ b[i]);
319
+ accu += popcount64(a[i] ^ b[i]);
263
320
  return accu;
264
321
  }
265
-
266
322
  };
267
323
 
268
- // even more inefficient!
324
+ // more inefficient than HammingComputerDefault (obsolete)
269
325
  struct HammingComputerM4 {
270
- const uint32_t *a;
326
+ const uint32_t* a;
271
327
  int n;
272
328
 
273
- HammingComputerM4 () {}
329
+ HammingComputerM4() {}
274
330
 
275
- HammingComputerM4 (const uint8_t *a4, int code_size) {
276
- set (a4, code_size);
331
+ HammingComputerM4(const uint8_t* a4, int code_size) {
332
+ set(a4, code_size);
277
333
  }
278
334
 
279
- void set (const uint8_t *a4, int code_size) {
280
- assert (code_size % 4 == 0);
281
- a = (uint32_t *)a4;
335
+ void set(const uint8_t* a4, int code_size) {
336
+ assert(code_size % 4 == 0);
337
+ a = (uint32_t*)a4;
282
338
  n = code_size / 4;
283
339
  }
284
340
 
285
- int hamming (const uint8_t *b8) const {
286
- const uint32_t *b = (uint32_t *)b8;
341
+ int hamming(const uint8_t* b8) const {
342
+ const uint32_t* b = (uint32_t*)b8;
287
343
  int accu = 0;
288
344
  for (int i = 0; i < n; i++)
289
- accu += popcount64 (a[i] ^ b[i]);
345
+ accu += popcount64(a[i] ^ b[i]);
290
346
  return accu;
291
347
  }
292
-
293
348
  };
294
349
 
295
350
  /***************************************************************************
@@ -297,17 +352,17 @@ struct HammingComputerM4 {
297
352
  **************************************************************************/
298
353
 
299
354
  // default template
300
- template<int CODE_SIZE>
301
- struct HammingComputer: HammingComputerM8 {
302
- HammingComputer (const uint8_t *a, int code_size):
303
- HammingComputerM8(a, code_size) {}
355
+ template <int CODE_SIZE>
356
+ struct HammingComputer : HammingComputerDefault {
357
+ HammingComputer(const uint8_t* a, int code_size)
358
+ : HammingComputerDefault(a, code_size) {}
304
359
  };
305
360
 
306
- #define SPECIALIZED_HC(CODE_SIZE) \
307
- template<> struct HammingComputer<CODE_SIZE>: \
308
- HammingComputer ## CODE_SIZE { \
309
- HammingComputer (const uint8_t *a): \
310
- HammingComputer ## CODE_SIZE(a, CODE_SIZE) {} \
361
+ #define SPECIALIZED_HC(CODE_SIZE) \
362
+ template <> \
363
+ struct HammingComputer<CODE_SIZE> : HammingComputer##CODE_SIZE { \
364
+ HammingComputer(const uint8_t* a) \
365
+ : HammingComputer##CODE_SIZE(a, CODE_SIZE) {} \
311
366
  }
312
367
 
313
368
  SPECIALIZED_HC(4);
@@ -319,105 +374,98 @@ SPECIALIZED_HC(64);
319
374
 
320
375
  #undef SPECIALIZED_HC
321
376
 
322
-
323
377
  /***************************************************************************
324
378
  * generalized Hamming = number of bytes that are different between
325
379
  * two codes.
326
380
  ***************************************************************************/
327
381
 
328
-
329
- inline int generalized_hamming_64 (uint64_t a) {
382
+ inline int generalized_hamming_64(uint64_t a) {
330
383
  a |= a >> 1;
331
384
  a |= a >> 2;
332
385
  a |= a >> 4;
333
386
  a &= 0x0101010101010101UL;
334
- return popcount64 (a);
387
+ return popcount64(a);
335
388
  }
336
389
 
337
-
338
390
  struct GenHammingComputer8 {
339
391
  uint64_t a0;
340
392
 
341
- GenHammingComputer8 (const uint8_t *a, int code_size) {
342
- assert (code_size == 8);
343
- a0 = *(uint64_t *)a;
393
+ GenHammingComputer8(const uint8_t* a, int code_size) {
394
+ assert(code_size == 8);
395
+ a0 = *(uint64_t*)a;
344
396
  }
345
397
 
346
- inline int hamming (const uint8_t *b) const {
347
- return generalized_hamming_64 (*(uint64_t *)b ^ a0);
398
+ inline int hamming(const uint8_t* b) const {
399
+ return generalized_hamming_64(*(uint64_t*)b ^ a0);
348
400
  }
349
-
350
401
  };
351
402
 
352
-
353
403
  struct GenHammingComputer16 {
354
404
  uint64_t a0, a1;
355
- GenHammingComputer16 (const uint8_t *a8, int code_size) {
356
- assert (code_size == 16);
357
- const uint64_t *a = (uint64_t *)a8;
358
- a0 = a[0]; a1 = a[1];
405
+ GenHammingComputer16(const uint8_t* a8, int code_size) {
406
+ assert(code_size == 16);
407
+ const uint64_t* a = (uint64_t*)a8;
408
+ a0 = a[0];
409
+ a1 = a[1];
359
410
  }
360
411
 
361
- inline int hamming (const uint8_t *b8) const {
362
- const uint64_t *b = (uint64_t *)b8;
363
- return generalized_hamming_64 (b[0] ^ a0) +
364
- generalized_hamming_64 (b[1] ^ a1);
412
+ inline int hamming(const uint8_t* b8) const {
413
+ const uint64_t* b = (uint64_t*)b8;
414
+ return generalized_hamming_64(b[0] ^ a0) +
415
+ generalized_hamming_64(b[1] ^ a1);
365
416
  }
366
-
367
417
  };
368
418
 
369
419
  struct GenHammingComputer32 {
370
420
  uint64_t a0, a1, a2, a3;
371
421
 
372
- GenHammingComputer32 (const uint8_t *a8, int code_size) {
373
- assert (code_size == 32);
374
- const uint64_t *a = (uint64_t *)a8;
375
- a0 = a[0]; a1 = a[1]; a2 = a[2]; a3 = a[3];
422
+ GenHammingComputer32(const uint8_t* a8, int code_size) {
423
+ assert(code_size == 32);
424
+ const uint64_t* a = (uint64_t*)a8;
425
+ a0 = a[0];
426
+ a1 = a[1];
427
+ a2 = a[2];
428
+ a3 = a[3];
376
429
  }
377
430
 
378
- inline int hamming (const uint8_t *b8) const {
379
- const uint64_t *b = (uint64_t *)b8;
380
- return generalized_hamming_64 (b[0] ^ a0) +
381
- generalized_hamming_64 (b[1] ^ a1) +
382
- generalized_hamming_64 (b[2] ^ a2) +
383
- generalized_hamming_64 (b[3] ^ a3);
431
+ inline int hamming(const uint8_t* b8) const {
432
+ const uint64_t* b = (uint64_t*)b8;
433
+ return generalized_hamming_64(b[0] ^ a0) +
434
+ generalized_hamming_64(b[1] ^ a1) +
435
+ generalized_hamming_64(b[2] ^ a2) +
436
+ generalized_hamming_64(b[3] ^ a3);
384
437
  }
385
-
386
438
  };
387
439
 
388
440
  struct GenHammingComputerM8 {
389
- const uint64_t *a;
441
+ const uint64_t* a;
390
442
  int n;
391
443
 
392
- GenHammingComputerM8 (const uint8_t *a8, int code_size) {
393
- assert (code_size % 8 == 0);
394
- a = (uint64_t *)a8;
444
+ GenHammingComputerM8(const uint8_t* a8, int code_size) {
445
+ assert(code_size % 8 == 0);
446
+ a = (uint64_t*)a8;
395
447
  n = code_size / 8;
396
448
  }
397
449
 
398
- int hamming (const uint8_t *b8) const {
399
- const uint64_t *b = (uint64_t *)b8;
450
+ int hamming(const uint8_t* b8) const {
451
+ const uint64_t* b = (uint64_t*)b8;
400
452
  int accu = 0;
401
453
  for (int i = 0; i < n; i++)
402
- accu += generalized_hamming_64 (a[i] ^ b[i]);
454
+ accu += generalized_hamming_64(a[i] ^ b[i]);
403
455
  return accu;
404
456
  }
405
-
406
457
  };
407
458
 
408
-
409
459
  /** generalized Hamming distances (= count number of code bytes that
410
460
  are the same) */
411
- void generalized_hammings_knn_hc (
412
- int_maxheap_array_t * ha,
413
- const uint8_t * a,
414
- const uint8_t * b,
461
+ void generalized_hammings_knn_hc(
462
+ int_maxheap_array_t* ha,
463
+ const uint8_t* a,
464
+ const uint8_t* b,
415
465
  size_t nb,
416
466
  size_t code_size,
417
467
  int ordered = true);
418
468
 
419
-
420
-
421
469
  /** This class maintains a list of best distances seen so far.
422
470
  *
423
471
  * Since the distances are in a limited range (0 to nbit), the
@@ -425,46 +473,49 @@ void generalized_hammings_knn_hc (
425
473
  * in only the n-first lists, such that the sum of sizes of the
426
474
  * n lists is below k.
427
475
  */
428
- template<class HammingComputer>
476
+ template <class HammingComputer>
429
477
  struct HCounterState {
430
- int *counters;
431
- int64_t *ids_per_dis;
432
-
433
- HammingComputer hc;
434
- int thres;
435
- int count_lt;
436
- int count_eq;
437
- int k;
438
-
439
- HCounterState(int *counters, int64_t *ids_per_dis,
440
- const uint8_t *x, int d, int k)
441
- : counters(counters),
442
- ids_per_dis(ids_per_dis),
443
- hc(x, d / 8),
444
- thres(d + 1),
445
- count_lt(0),
446
- count_eq(0),
447
- k(k) {}
448
-
449
- void update_counter(const uint8_t *y, size_t j) {
450
- int32_t dis = hc.hamming(y);
451
-
452
- if (dis <= thres) {
453
- if (dis < thres) {
454
- ids_per_dis[dis * k + counters[dis]++] = j;
455
- ++count_lt;
456
- while (count_lt == k && thres > 0) {
457
- --thres;
458
- count_eq = counters[thres];
459
- count_lt -= count_eq;
478
+ int* counters;
479
+ int64_t* ids_per_dis;
480
+
481
+ HammingComputer hc;
482
+ int thres;
483
+ int count_lt;
484
+ int count_eq;
485
+ int k;
486
+
487
+ HCounterState(
488
+ int* counters,
489
+ int64_t* ids_per_dis,
490
+ const uint8_t* x,
491
+ int d,
492
+ int k)
493
+ : counters(counters),
494
+ ids_per_dis(ids_per_dis),
495
+ hc(x, d / 8),
496
+ thres(d + 1),
497
+ count_lt(0),
498
+ count_eq(0),
499
+ k(k) {}
500
+
501
+ void update_counter(const uint8_t* y, size_t j) {
502
+ int32_t dis = hc.hamming(y);
503
+
504
+ if (dis <= thres) {
505
+ if (dis < thres) {
506
+ ids_per_dis[dis * k + counters[dis]++] = j;
507
+ ++count_lt;
508
+ while (count_lt == k && thres > 0) {
509
+ --thres;
510
+ count_eq = counters[thres];
511
+ count_lt -= count_eq;
512
+ }
513
+ } else if (count_eq < k) {
514
+ ids_per_dis[dis * k + count_eq++] = j;
515
+ counters[dis] = count_eq;
516
+ }
460
517
  }
461
- } else if (count_eq < k) {
462
- ids_per_dis[dis * k + count_eq++] = j;
463
- counters[dis] = count_eq;
464
- }
465
518
  }
466
- }
467
519
  };
468
520
 
469
-
470
521
  } // namespace faiss