faiss 0.2.0 → 0.2.1

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/faiss/version.rb +1 -1
  4. data/vendor/faiss/faiss/AutoTune.cpp +292 -291
  5. data/vendor/faiss/faiss/AutoTune.h +55 -56
  6. data/vendor/faiss/faiss/Clustering.cpp +334 -195
  7. data/vendor/faiss/faiss/Clustering.h +88 -35
  8. data/vendor/faiss/faiss/IVFlib.cpp +171 -195
  9. data/vendor/faiss/faiss/IVFlib.h +48 -51
  10. data/vendor/faiss/faiss/Index.cpp +85 -103
  11. data/vendor/faiss/faiss/Index.h +54 -48
  12. data/vendor/faiss/faiss/Index2Layer.cpp +139 -164
  13. data/vendor/faiss/faiss/Index2Layer.h +22 -22
  14. data/vendor/faiss/faiss/IndexBinary.cpp +45 -37
  15. data/vendor/faiss/faiss/IndexBinary.h +140 -132
  16. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +73 -53
  17. data/vendor/faiss/faiss/IndexBinaryFlat.h +29 -24
  18. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +46 -43
  19. data/vendor/faiss/faiss/IndexBinaryFromFloat.h +16 -15
  20. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +215 -232
  21. data/vendor/faiss/faiss/IndexBinaryHNSW.h +25 -24
  22. data/vendor/faiss/faiss/IndexBinaryHash.cpp +182 -177
  23. data/vendor/faiss/faiss/IndexBinaryHash.h +41 -34
  24. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +489 -461
  25. data/vendor/faiss/faiss/IndexBinaryIVF.h +97 -68
  26. data/vendor/faiss/faiss/IndexFlat.cpp +116 -147
  27. data/vendor/faiss/faiss/IndexFlat.h +35 -46
  28. data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
  29. data/vendor/faiss/faiss/IndexHNSW.h +57 -41
  30. data/vendor/faiss/faiss/IndexIVF.cpp +474 -454
  31. data/vendor/faiss/faiss/IndexIVF.h +146 -113
  32. data/vendor/faiss/faiss/IndexIVFFlat.cpp +248 -250
  33. data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
  34. data/vendor/faiss/faiss/IndexIVFPQ.cpp +457 -516
  35. data/vendor/faiss/faiss/IndexIVFPQ.h +74 -66
  36. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +406 -372
  37. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +82 -57
  38. data/vendor/faiss/faiss/IndexIVFPQR.cpp +104 -102
  39. data/vendor/faiss/faiss/IndexIVFPQR.h +33 -28
  40. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +125 -133
  41. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +19 -21
  42. data/vendor/faiss/faiss/IndexLSH.cpp +75 -96
  43. data/vendor/faiss/faiss/IndexLSH.h +21 -26
  44. data/vendor/faiss/faiss/IndexLattice.cpp +42 -56
  45. data/vendor/faiss/faiss/IndexLattice.h +11 -16
  46. data/vendor/faiss/faiss/IndexNNDescent.cpp +231 -0
  47. data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
  48. data/vendor/faiss/faiss/IndexNSG.cpp +303 -0
  49. data/vendor/faiss/faiss/IndexNSG.h +85 -0
  50. data/vendor/faiss/faiss/IndexPQ.cpp +405 -464
  51. data/vendor/faiss/faiss/IndexPQ.h +64 -67
  52. data/vendor/faiss/faiss/IndexPQFastScan.cpp +143 -170
  53. data/vendor/faiss/faiss/IndexPQFastScan.h +46 -32
  54. data/vendor/faiss/faiss/IndexPreTransform.cpp +120 -150
  55. data/vendor/faiss/faiss/IndexPreTransform.h +33 -36
  56. data/vendor/faiss/faiss/IndexRefine.cpp +115 -131
  57. data/vendor/faiss/faiss/IndexRefine.h +22 -23
  58. data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
  59. data/vendor/faiss/faiss/IndexReplicas.h +62 -56
  60. data/vendor/faiss/faiss/IndexResidual.cpp +291 -0
  61. data/vendor/faiss/faiss/IndexResidual.h +152 -0
  62. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +120 -155
  63. data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -45
  64. data/vendor/faiss/faiss/IndexShards.cpp +256 -240
  65. data/vendor/faiss/faiss/IndexShards.h +85 -73
  66. data/vendor/faiss/faiss/MatrixStats.cpp +112 -97
  67. data/vendor/faiss/faiss/MatrixStats.h +7 -10
  68. data/vendor/faiss/faiss/MetaIndexes.cpp +135 -157
  69. data/vendor/faiss/faiss/MetaIndexes.h +40 -34
  70. data/vendor/faiss/faiss/MetricType.h +7 -7
  71. data/vendor/faiss/faiss/VectorTransform.cpp +652 -474
  72. data/vendor/faiss/faiss/VectorTransform.h +61 -89
  73. data/vendor/faiss/faiss/clone_index.cpp +77 -73
  74. data/vendor/faiss/faiss/clone_index.h +4 -9
  75. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +33 -38
  76. data/vendor/faiss/faiss/gpu/GpuAutoTune.h +11 -9
  77. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +197 -170
  78. data/vendor/faiss/faiss/gpu/GpuCloner.h +53 -35
  79. data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +12 -14
  80. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +27 -25
  81. data/vendor/faiss/faiss/gpu/GpuDistance.h +116 -112
  82. data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -2
  83. data/vendor/faiss/faiss/gpu/GpuIndex.h +134 -137
  84. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +76 -73
  85. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +173 -162
  86. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +67 -64
  87. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +89 -86
  88. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +150 -141
  89. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +101 -103
  90. data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +17 -16
  91. data/vendor/faiss/faiss/gpu/GpuResources.cpp +116 -128
  92. data/vendor/faiss/faiss/gpu/GpuResources.h +182 -186
  93. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +433 -422
  94. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +131 -130
  95. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +468 -456
  96. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +25 -19
  97. data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +22 -20
  98. data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +9 -8
  99. data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +39 -44
  100. data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +16 -14
  101. data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +77 -71
  102. data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +109 -88
  103. data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +75 -64
  104. data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +230 -215
  105. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +80 -86
  106. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +284 -277
  107. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +416 -416
  108. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +611 -517
  109. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +166 -164
  110. data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +61 -53
  111. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +274 -238
  112. data/vendor/faiss/faiss/gpu/test/TestUtils.h +73 -57
  113. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +47 -50
  114. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +79 -72
  115. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +140 -146
  116. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +69 -71
  117. data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +21 -16
  118. data/vendor/faiss/faiss/gpu/utils/Timer.cpp +25 -29
  119. data/vendor/faiss/faiss/gpu/utils/Timer.h +30 -29
  120. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +270 -0
  121. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +115 -0
  122. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +90 -120
  123. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +81 -65
  124. data/vendor/faiss/faiss/impl/FaissAssert.h +73 -58
  125. data/vendor/faiss/faiss/impl/FaissException.cpp +56 -48
  126. data/vendor/faiss/faiss/impl/FaissException.h +41 -29
  127. data/vendor/faiss/faiss/impl/HNSW.cpp +595 -611
  128. data/vendor/faiss/faiss/impl/HNSW.h +179 -200
  129. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +672 -0
  130. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +172 -0
  131. data/vendor/faiss/faiss/impl/NNDescent.cpp +487 -0
  132. data/vendor/faiss/faiss/impl/NNDescent.h +154 -0
  133. data/vendor/faiss/faiss/impl/NSG.cpp +682 -0
  134. data/vendor/faiss/faiss/impl/NSG.h +199 -0
  135. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +484 -454
  136. data/vendor/faiss/faiss/impl/PolysemousTraining.h +52 -55
  137. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +26 -47
  138. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +469 -459
  139. data/vendor/faiss/faiss/impl/ProductQuantizer.h +76 -87
  140. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +448 -0
  141. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +130 -0
  142. data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
  143. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +648 -701
  144. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +48 -46
  145. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +129 -131
  146. data/vendor/faiss/faiss/impl/ThreadedIndex.h +61 -55
  147. data/vendor/faiss/faiss/impl/index_read.cpp +547 -479
  148. data/vendor/faiss/faiss/impl/index_write.cpp +497 -407
  149. data/vendor/faiss/faiss/impl/io.cpp +75 -94
  150. data/vendor/faiss/faiss/impl/io.h +31 -41
  151. data/vendor/faiss/faiss/impl/io_macros.h +40 -29
  152. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +137 -186
  153. data/vendor/faiss/faiss/impl/lattice_Zn.h +40 -51
  154. data/vendor/faiss/faiss/impl/platform_macros.h +29 -8
  155. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +77 -124
  156. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +39 -48
  157. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +41 -52
  158. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +80 -117
  159. data/vendor/faiss/faiss/impl/simd_result_handlers.h +109 -137
  160. data/vendor/faiss/faiss/index_factory.cpp +269 -218
  161. data/vendor/faiss/faiss/index_factory.h +6 -7
  162. data/vendor/faiss/faiss/index_io.h +23 -26
  163. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +67 -75
  164. data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +22 -24
  165. data/vendor/faiss/faiss/invlists/DirectMap.cpp +96 -112
  166. data/vendor/faiss/faiss/invlists/DirectMap.h +29 -33
  167. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +307 -364
  168. data/vendor/faiss/faiss/invlists/InvertedLists.h +151 -151
  169. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +29 -34
  170. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +17 -18
  171. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +257 -293
  172. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +50 -45
  173. data/vendor/faiss/faiss/python/python_callbacks.cpp +23 -26
  174. data/vendor/faiss/faiss/python/python_callbacks.h +9 -16
  175. data/vendor/faiss/faiss/utils/AlignedTable.h +79 -44
  176. data/vendor/faiss/faiss/utils/Heap.cpp +40 -48
  177. data/vendor/faiss/faiss/utils/Heap.h +186 -209
  178. data/vendor/faiss/faiss/utils/WorkerThread.cpp +67 -76
  179. data/vendor/faiss/faiss/utils/WorkerThread.h +32 -33
  180. data/vendor/faiss/faiss/utils/distances.cpp +301 -310
  181. data/vendor/faiss/faiss/utils/distances.h +133 -118
  182. data/vendor/faiss/faiss/utils/distances_simd.cpp +456 -516
  183. data/vendor/faiss/faiss/utils/extra_distances-inl.h +117 -0
  184. data/vendor/faiss/faiss/utils/extra_distances.cpp +113 -232
  185. data/vendor/faiss/faiss/utils/extra_distances.h +30 -29
  186. data/vendor/faiss/faiss/utils/hamming-inl.h +260 -209
  187. data/vendor/faiss/faiss/utils/hamming.cpp +375 -469
  188. data/vendor/faiss/faiss/utils/hamming.h +62 -85
  189. data/vendor/faiss/faiss/utils/ordered_key_value.h +16 -18
  190. data/vendor/faiss/faiss/utils/partitioning.cpp +393 -318
  191. data/vendor/faiss/faiss/utils/partitioning.h +26 -21
  192. data/vendor/faiss/faiss/utils/quantize_lut.cpp +78 -66
  193. data/vendor/faiss/faiss/utils/quantize_lut.h +22 -20
  194. data/vendor/faiss/faiss/utils/random.cpp +39 -63
  195. data/vendor/faiss/faiss/utils/random.h +13 -16
  196. data/vendor/faiss/faiss/utils/simdlib.h +4 -2
  197. data/vendor/faiss/faiss/utils/simdlib_avx2.h +88 -85
  198. data/vendor/faiss/faiss/utils/simdlib_emulated.h +226 -165
  199. data/vendor/faiss/faiss/utils/simdlib_neon.h +832 -0
  200. data/vendor/faiss/faiss/utils/utils.cpp +304 -287
  201. data/vendor/faiss/faiss/utils/utils.h +53 -48
  202. metadata +20 -2
@@ -5,10 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- // -*- c++ -*-
9
-
10
- #ifndef FAISS_distances_h
11
- #define FAISS_distances_h
8
+ #pragma once
12
9
 
13
10
  /** In this file are the implementations of extra metrics beyond L2
14
11
  * and inner product */
@@ -19,36 +16,40 @@
19
16
 
20
17
  #include <faiss/utils/Heap.h>
21
18
 
22
-
23
-
24
19
  namespace faiss {
25
20
 
26
-
27
- void pairwise_extra_distances (
28
- int64_t d,
29
- int64_t nq, const float *xq,
30
- int64_t nb, const float *xb,
31
- MetricType mt, float metric_arg,
32
- float *dis,
33
- int64_t ldq = -1, int64_t ldb = -1, int64_t ldd = -1);
34
-
35
-
36
- void knn_extra_metrics (
37
- const float * x,
38
- const float * y,
39
- size_t d, size_t nx, size_t ny,
40
- MetricType mt, float metric_arg,
41
- float_maxheap_array_t * res);
42
-
21
+ void pairwise_extra_distances(
22
+ int64_t d,
23
+ int64_t nq,
24
+ const float* xq,
25
+ int64_t nb,
26
+ const float* xb,
27
+ MetricType mt,
28
+ float metric_arg,
29
+ float* dis,
30
+ int64_t ldq = -1,
31
+ int64_t ldb = -1,
32
+ int64_t ldd = -1);
33
+
34
+ void knn_extra_metrics(
35
+ const float* x,
36
+ const float* y,
37
+ size_t d,
38
+ size_t nx,
39
+ size_t ny,
40
+ MetricType mt,
41
+ float metric_arg,
42
+ float_maxheap_array_t* res);
43
43
 
44
44
  /** get a DistanceComputer that refers to this type of distance and
45
45
  * indexes a flat array of size nb */
46
- DistanceComputer *get_extra_distance_computer (
46
+ DistanceComputer* get_extra_distance_computer(
47
47
  size_t d,
48
- MetricType mt, float metric_arg,
49
- size_t nb, const float *xb);
50
-
51
- }
48
+ MetricType mt,
49
+ float metric_arg,
50
+ size_t nb,
51
+ const float* xb);
52
52
 
53
+ } // namespace faiss
53
54
 
54
- #endif
55
+ #include <faiss/utils/extra_distances-inl.h>
@@ -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