faiss 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1 -1
  5. data/ext/faiss/extconf.rb +9 -2
  6. data/ext/faiss/index.cpp +1 -1
  7. data/ext/faiss/index_binary.cpp +2 -2
  8. data/ext/faiss/product_quantizer.cpp +1 -1
  9. data/lib/faiss/version.rb +1 -1
  10. data/vendor/faiss/faiss/AutoTune.cpp +7 -7
  11. data/vendor/faiss/faiss/AutoTune.h +1 -2
  12. data/vendor/faiss/faiss/Clustering.cpp +39 -22
  13. data/vendor/faiss/faiss/Clustering.h +40 -21
  14. data/vendor/faiss/faiss/IVFlib.cpp +26 -12
  15. data/vendor/faiss/faiss/Index.cpp +1 -1
  16. data/vendor/faiss/faiss/Index.h +40 -10
  17. data/vendor/faiss/faiss/Index2Layer.cpp +7 -7
  18. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +176 -166
  19. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +15 -15
  20. data/vendor/faiss/faiss/IndexBinary.cpp +9 -4
  21. data/vendor/faiss/faiss/IndexBinary.h +8 -19
  22. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +2 -1
  23. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +24 -31
  24. data/vendor/faiss/faiss/IndexBinaryHNSW.h +1 -1
  25. data/vendor/faiss/faiss/IndexBinaryHash.cpp +25 -50
  26. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +107 -188
  27. data/vendor/faiss/faiss/IndexFastScan.cpp +95 -146
  28. data/vendor/faiss/faiss/IndexFastScan.h +9 -8
  29. data/vendor/faiss/faiss/IndexFlat.cpp +206 -10
  30. data/vendor/faiss/faiss/IndexFlat.h +20 -1
  31. data/vendor/faiss/faiss/IndexFlatCodes.cpp +170 -5
  32. data/vendor/faiss/faiss/IndexFlatCodes.h +23 -4
  33. data/vendor/faiss/faiss/IndexHNSW.cpp +231 -382
  34. data/vendor/faiss/faiss/IndexHNSW.h +62 -49
  35. data/vendor/faiss/faiss/IndexIDMap.cpp +69 -28
  36. data/vendor/faiss/faiss/IndexIDMap.h +24 -2
  37. data/vendor/faiss/faiss/IndexIVF.cpp +162 -56
  38. data/vendor/faiss/faiss/IndexIVF.h +46 -6
  39. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +33 -26
  40. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +6 -2
  41. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +19 -46
  42. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -3
  43. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +502 -401
  44. data/vendor/faiss/faiss/IndexIVFFastScan.h +63 -26
  45. data/vendor/faiss/faiss/IndexIVFFlat.cpp +15 -5
  46. data/vendor/faiss/faiss/IndexIVFFlat.h +3 -2
  47. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +172 -0
  48. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.h +56 -0
  49. data/vendor/faiss/faiss/IndexIVFPQ.cpp +79 -125
  50. data/vendor/faiss/faiss/IndexIVFPQ.h +6 -7
  51. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +39 -52
  52. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +4 -3
  53. data/vendor/faiss/faiss/IndexIVFPQR.cpp +45 -29
  54. data/vendor/faiss/faiss/IndexIVFPQR.h +5 -2
  55. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +25 -27
  56. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +6 -6
  57. data/vendor/faiss/faiss/IndexLSH.cpp +14 -16
  58. data/vendor/faiss/faiss/IndexLattice.cpp +1 -19
  59. data/vendor/faiss/faiss/IndexLattice.h +3 -22
  60. data/vendor/faiss/faiss/IndexNNDescent.cpp +3 -33
  61. data/vendor/faiss/faiss/IndexNNDescent.h +1 -1
  62. data/vendor/faiss/faiss/IndexNSG.cpp +11 -27
  63. data/vendor/faiss/faiss/IndexNSG.h +11 -11
  64. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +56 -0
  65. data/vendor/faiss/faiss/IndexNeuralNetCodec.h +49 -0
  66. data/vendor/faiss/faiss/IndexPQ.cpp +72 -88
  67. data/vendor/faiss/faiss/IndexPQ.h +1 -4
  68. data/vendor/faiss/faiss/IndexPQFastScan.cpp +1 -1
  69. data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -31
  70. data/vendor/faiss/faiss/IndexPreTransform.h +1 -1
  71. data/vendor/faiss/faiss/IndexRefine.cpp +54 -24
  72. data/vendor/faiss/faiss/IndexRefine.h +7 -0
  73. data/vendor/faiss/faiss/IndexReplicas.cpp +23 -26
  74. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +25 -17
  75. data/vendor/faiss/faiss/IndexScalarQuantizer.h +6 -4
  76. data/vendor/faiss/faiss/IndexShards.cpp +21 -29
  77. data/vendor/faiss/faiss/IndexShardsIVF.cpp +1 -2
  78. data/vendor/faiss/faiss/MatrixStats.cpp +17 -32
  79. data/vendor/faiss/faiss/MatrixStats.h +21 -9
  80. data/vendor/faiss/faiss/MetaIndexes.cpp +35 -35
  81. data/vendor/faiss/faiss/MetricType.h +7 -2
  82. data/vendor/faiss/faiss/VectorTransform.cpp +13 -26
  83. data/vendor/faiss/faiss/VectorTransform.h +7 -7
  84. data/vendor/faiss/faiss/clone_index.cpp +15 -10
  85. data/vendor/faiss/faiss/clone_index.h +3 -0
  86. data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +95 -17
  87. data/vendor/faiss/faiss/cppcontrib/factory_tools.cpp +152 -0
  88. data/vendor/faiss/faiss/cppcontrib/factory_tools.h +24 -0
  89. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +83 -30
  90. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +123 -8
  91. data/vendor/faiss/faiss/gpu/GpuCloner.h +22 -0
  92. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +13 -0
  93. data/vendor/faiss/faiss/gpu/GpuDistance.h +46 -38
  94. data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -1
  95. data/vendor/faiss/faiss/gpu/GpuIndex.h +30 -12
  96. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +282 -0
  97. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +4 -4
  98. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +14 -9
  99. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +20 -3
  100. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -11
  101. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +1 -3
  102. data/vendor/faiss/faiss/gpu/GpuResources.cpp +24 -3
  103. data/vendor/faiss/faiss/gpu/GpuResources.h +39 -11
  104. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +142 -17
  105. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +57 -3
  106. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +26 -21
  107. data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +7 -1
  108. data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +8 -5
  109. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +25 -0
  110. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +129 -9
  111. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +332 -40
  112. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +299 -208
  113. data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +1 -0
  114. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +1 -1
  115. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +6 -0
  116. data/vendor/faiss/faiss/gpu/utils/RaftUtils.h +75 -0
  117. data/vendor/faiss/faiss/gpu/utils/Timer.cpp +4 -1
  118. data/vendor/faiss/faiss/gpu/utils/Timer.h +1 -1
  119. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +3 -1
  120. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +5 -5
  121. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +26 -1
  122. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +10 -3
  123. data/vendor/faiss/faiss/impl/DistanceComputer.h +70 -1
  124. data/vendor/faiss/faiss/impl/FaissAssert.h +4 -2
  125. data/vendor/faiss/faiss/impl/FaissException.h +13 -34
  126. data/vendor/faiss/faiss/impl/HNSW.cpp +605 -186
  127. data/vendor/faiss/faiss/impl/HNSW.h +52 -30
  128. data/vendor/faiss/faiss/impl/IDSelector.h +4 -4
  129. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +11 -9
  130. data/vendor/faiss/faiss/impl/LookupTableScaler.h +34 -0
  131. data/vendor/faiss/faiss/impl/NNDescent.cpp +42 -27
  132. data/vendor/faiss/faiss/impl/NSG.cpp +0 -29
  133. data/vendor/faiss/faiss/impl/NSG.h +1 -1
  134. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +14 -12
  135. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +1 -1
  136. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +25 -22
  137. data/vendor/faiss/faiss/impl/ProductQuantizer.h +6 -2
  138. data/vendor/faiss/faiss/impl/Quantizer.h +1 -1
  139. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +27 -1015
  140. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +5 -63
  141. data/vendor/faiss/faiss/impl/ResultHandler.h +347 -172
  142. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +1104 -147
  143. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +3 -8
  144. data/vendor/faiss/faiss/impl/code_distance/code_distance-avx2.h +285 -42
  145. data/vendor/faiss/faiss/impl/code_distance/code_distance-avx512.h +248 -0
  146. data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +21 -14
  147. data/vendor/faiss/faiss/impl/code_distance/code_distance.h +22 -12
  148. data/vendor/faiss/faiss/impl/index_read.cpp +74 -34
  149. data/vendor/faiss/faiss/impl/index_read_utils.h +37 -0
  150. data/vendor/faiss/faiss/impl/index_write.cpp +88 -51
  151. data/vendor/faiss/faiss/impl/io.cpp +23 -15
  152. data/vendor/faiss/faiss/impl/io.h +4 -4
  153. data/vendor/faiss/faiss/impl/io_macros.h +6 -0
  154. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +1 -1
  155. data/vendor/faiss/faiss/impl/platform_macros.h +40 -1
  156. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +14 -0
  157. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +7 -6
  158. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +52 -38
  159. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +487 -49
  160. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +960 -0
  161. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +176 -0
  162. data/vendor/faiss/faiss/impl/simd_result_handlers.h +481 -225
  163. data/vendor/faiss/faiss/index_factory.cpp +41 -20
  164. data/vendor/faiss/faiss/index_io.h +12 -5
  165. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +28 -8
  166. data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +3 -0
  167. data/vendor/faiss/faiss/invlists/DirectMap.cpp +10 -2
  168. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +73 -17
  169. data/vendor/faiss/faiss/invlists/InvertedLists.h +26 -8
  170. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +24 -9
  171. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +2 -1
  172. data/vendor/faiss/faiss/python/python_callbacks.cpp +4 -4
  173. data/vendor/faiss/faiss/utils/Heap.cpp +3 -1
  174. data/vendor/faiss/faiss/utils/Heap.h +105 -0
  175. data/vendor/faiss/faiss/utils/NeuralNet.cpp +342 -0
  176. data/vendor/faiss/faiss/utils/NeuralNet.h +147 -0
  177. data/vendor/faiss/faiss/utils/WorkerThread.h +1 -0
  178. data/vendor/faiss/faiss/utils/bf16.h +36 -0
  179. data/vendor/faiss/faiss/utils/distances.cpp +147 -123
  180. data/vendor/faiss/faiss/utils/distances.h +86 -9
  181. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +5 -5
  182. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +2 -2
  183. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +2 -2
  184. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +1 -1
  185. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +5 -5
  186. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.h +1 -1
  187. data/vendor/faiss/faiss/utils/distances_simd.cpp +1589 -243
  188. data/vendor/faiss/faiss/utils/extra_distances-inl.h +70 -0
  189. data/vendor/faiss/faiss/utils/extra_distances.cpp +85 -137
  190. data/vendor/faiss/faiss/utils/extra_distances.h +3 -2
  191. data/vendor/faiss/faiss/utils/fp16-arm.h +29 -0
  192. data/vendor/faiss/faiss/utils/fp16.h +2 -0
  193. data/vendor/faiss/faiss/utils/hamming.cpp +163 -111
  194. data/vendor/faiss/faiss/utils/hamming.h +58 -0
  195. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +16 -89
  196. data/vendor/faiss/faiss/utils/hamming_distance/common.h +1 -0
  197. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +19 -88
  198. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +58 -0
  199. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +14 -104
  200. data/vendor/faiss/faiss/utils/partitioning.cpp +3 -4
  201. data/vendor/faiss/faiss/utils/prefetch.h +77 -0
  202. data/vendor/faiss/faiss/utils/quantize_lut.cpp +0 -14
  203. data/vendor/faiss/faiss/utils/random.cpp +43 -0
  204. data/vendor/faiss/faiss/utils/random.h +25 -0
  205. data/vendor/faiss/faiss/utils/simdlib.h +10 -1
  206. data/vendor/faiss/faiss/utils/simdlib_avx2.h +0 -6
  207. data/vendor/faiss/faiss/utils/simdlib_avx512.h +296 -0
  208. data/vendor/faiss/faiss/utils/simdlib_neon.h +77 -79
  209. data/vendor/faiss/faiss/utils/simdlib_ppc64.h +1084 -0
  210. data/vendor/faiss/faiss/utils/sorting.cpp +140 -5
  211. data/vendor/faiss/faiss/utils/sorting.h +27 -0
  212. data/vendor/faiss/faiss/utils/transpose/transpose-avx512-inl.h +176 -0
  213. data/vendor/faiss/faiss/utils/utils.cpp +120 -7
  214. data/vendor/faiss/faiss/utils/utils.h +60 -20
  215. metadata +23 -4
  216. data/vendor/faiss/faiss/impl/code_distance/code_distance_avx512.h +0 -102
@@ -24,29 +24,29 @@ namespace faiss {
24
24
  * link structure built on top */
25
25
 
26
26
  struct IndexNSG : Index {
27
- /// the link strcuture
27
+ /// the link structure
28
28
  NSG nsg;
29
29
 
30
30
  /// the sequential storage
31
- bool own_fields;
32
- Index* storage;
31
+ bool own_fields = false;
32
+ Index* storage = nullptr;
33
33
 
34
34
  /// the index is built or not
35
- bool is_built;
35
+ bool is_built = false;
36
36
 
37
37
  /// K of KNN graph for building
38
- int GK;
38
+ int GK = 64;
39
39
 
40
40
  /// indicate how to build a knn graph
41
41
  /// - 0: build NSG with brute force search
42
42
  /// - 1: build NSG with NNDescent
43
- char build_type;
43
+ char build_type = 0;
44
44
 
45
45
  /// parameters for nndescent
46
- int nndescent_S;
47
- int nndescent_R;
48
- int nndescent_L;
49
- int nndescent_iter;
46
+ int nndescent_S = 10;
47
+ int nndescent_R = 100;
48
+ int nndescent_L; // set to GK + 50
49
+ int nndescent_iter = 10;
50
50
 
51
51
  explicit IndexNSG(int d = 0, int R = 32, MetricType metric = METRIC_L2);
52
52
  explicit IndexNSG(Index* storage, int R = 32);
@@ -90,7 +90,7 @@ struct IndexNSGFlat : IndexNSG {
90
90
  */
91
91
  struct IndexNSGPQ : IndexNSG {
92
92
  IndexNSGPQ();
93
- IndexNSGPQ(int d, int pq_m, int M);
93
+ IndexNSGPQ(int d, int pq_m, int M, int pq_nbits = 8);
94
94
  void train(idx_t n, const float* x) override;
95
95
  };
96
96
 
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include <faiss/IndexNeuralNetCodec.h>
9
+ #include <faiss/impl/FaissAssert.h>
10
+ #include <faiss/utils/hamming.h>
11
+
12
+ namespace faiss {
13
+
14
+ /*********************************************************
15
+ * IndexNeuralNetCodec implementation
16
+ *********************************************************/
17
+
18
+ IndexNeuralNetCodec::IndexNeuralNetCodec(
19
+ int d,
20
+ int M,
21
+ int nbits,
22
+ MetricType metric)
23
+ : IndexFlatCodes((M * nbits + 7) / 8, d, metric), M(M), nbits(nbits) {
24
+ is_trained = false;
25
+ }
26
+
27
+ void IndexNeuralNetCodec::train(idx_t n, const float* x) {
28
+ FAISS_THROW_MSG("Training not implemented in C++, use Pytorch");
29
+ }
30
+
31
+ void IndexNeuralNetCodec::sa_encode(idx_t n, const float* x, uint8_t* codes)
32
+ const {
33
+ nn::Tensor2D x_tensor(n, d, x);
34
+ nn::Int32Tensor2D codes_tensor = net->encode(x_tensor);
35
+ pack_bitstrings(n, M, nbits, codes_tensor.data(), codes, code_size);
36
+ }
37
+
38
+ void IndexNeuralNetCodec::sa_decode(idx_t n, const uint8_t* codes, float* x)
39
+ const {
40
+ nn::Int32Tensor2D codes_tensor(n, M);
41
+ unpack_bitstrings(n, M, nbits, codes, code_size, codes_tensor.data());
42
+ nn::Tensor2D x_tensor = net->decode(codes_tensor);
43
+ memcpy(x, x_tensor.data(), d * n * sizeof(float));
44
+ }
45
+
46
+ /*********************************************************
47
+ * IndexQINeuralNetCodec implementation
48
+ *********************************************************/
49
+
50
+ IndexQINCo::IndexQINCo(int d, int M, int nbits, int L, int h, MetricType metric)
51
+ : IndexNeuralNetCodec(d, M, nbits, metric),
52
+ qinco(d, 1 << nbits, L, M, h) {
53
+ net = &qinco;
54
+ }
55
+
56
+ } // namespace faiss
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <vector>
11
+
12
+ #include <faiss/IndexFlatCodes.h>
13
+ #include <faiss/utils/NeuralNet.h>
14
+
15
+ namespace faiss {
16
+
17
+ struct IndexNeuralNetCodec : IndexFlatCodes {
18
+ NeuralNetCodec* net = nullptr;
19
+ size_t M, nbits;
20
+
21
+ explicit IndexNeuralNetCodec(
22
+ int d = 0,
23
+ int M = 0,
24
+ int nbits = 0,
25
+ MetricType metric = METRIC_L2);
26
+
27
+ void train(idx_t n, const float* x) override;
28
+
29
+ void sa_encode(idx_t n, const float* x, uint8_t* codes) const override;
30
+ void sa_decode(idx_t n, const uint8_t* codes, float* x) const override;
31
+
32
+ ~IndexNeuralNetCodec() {}
33
+ };
34
+
35
+ struct IndexQINCo : IndexNeuralNetCodec {
36
+ QINCo qinco;
37
+
38
+ IndexQINCo(
39
+ int d,
40
+ int M,
41
+ int nbits,
42
+ int L,
43
+ int h,
44
+ MetricType metric = METRIC_L2);
45
+
46
+ ~IndexQINCo() {}
47
+ };
48
+
49
+ } // namespace faiss
@@ -14,6 +14,7 @@
14
14
  #include <cstring>
15
15
 
16
16
  #include <algorithm>
17
+ #include <memory>
17
18
 
18
19
  #include <faiss/impl/DistanceComputer.h>
19
20
  #include <faiss/impl/FaissAssert.h>
@@ -86,7 +87,7 @@ struct PQDistanceComputer : FlatCodesDistanceComputer {
86
87
  ndis++;
87
88
 
88
89
  float dis = distance_single_code<PQDecoder>(
89
- pq, precomputed_table.data(), code);
90
+ pq.M, pq.nbits, precomputed_table.data(), code);
90
91
  return dis;
91
92
  }
92
93
 
@@ -198,17 +199,16 @@ void IndexPQ::search(
198
199
 
199
200
  } else { // code-to-code distances
200
201
 
201
- uint8_t* q_codes = new uint8_t[n * pq.code_size];
202
- ScopeDeleter<uint8_t> del(q_codes);
202
+ std::unique_ptr<uint8_t[]> q_codes(new uint8_t[n * pq.code_size]);
203
203
 
204
204
  if (!encode_signs) {
205
- pq.compute_codes(x, q_codes, n);
205
+ pq.compute_codes(x, q_codes.get(), n);
206
206
  } else {
207
207
  FAISS_THROW_IF_NOT(d == pq.nbits * pq.M);
208
- memset(q_codes, 0, n * pq.code_size);
208
+ memset(q_codes.get(), 0, n * pq.code_size);
209
209
  for (size_t i = 0; i < n; i++) {
210
210
  const float* xi = x + i * d;
211
- uint8_t* code = q_codes + i * pq.code_size;
211
+ uint8_t* code = q_codes.get() + i * pq.code_size;
212
212
  for (int j = 0; j < d; j++)
213
213
  if (xi[j] > 0)
214
214
  code[j >> 3] |= 1 << (j & 7);
@@ -219,19 +219,18 @@ void IndexPQ::search(
219
219
  float_maxheap_array_t res = {
220
220
  size_t(n), size_t(k), labels, distances};
221
221
 
222
- pq.search_sdc(q_codes, n, codes.data(), ntotal, &res, true);
222
+ pq.search_sdc(q_codes.get(), n, codes.data(), ntotal, &res, true);
223
223
 
224
224
  } else {
225
- int* idistances = new int[n * k];
226
- ScopeDeleter<int> del(idistances);
225
+ std::unique_ptr<int[]> idistances(new int[n * k]);
227
226
 
228
227
  int_maxheap_array_t res = {
229
- size_t(n), size_t(k), labels, idistances};
228
+ size_t(n), size_t(k), labels, idistances.get()};
230
229
 
231
230
  if (search_type == ST_HE) {
232
231
  hammings_knn_hc(
233
232
  &res,
234
- q_codes,
233
+ q_codes.get(),
235
234
  codes.data(),
236
235
  ntotal,
237
236
  pq.code_size,
@@ -240,7 +239,7 @@ void IndexPQ::search(
240
239
  } else if (search_type == ST_generalized_HE) {
241
240
  generalized_hammings_knn_hc(
242
241
  &res,
243
- q_codes,
242
+ q_codes.get(),
244
243
  codes.data(),
245
244
  ntotal,
246
245
  pq.code_size,
@@ -263,21 +262,23 @@ void IndexPQStats::reset() {
263
262
 
264
263
  IndexPQStats indexPQ_stats;
265
264
 
265
+ namespace {
266
+
266
267
  template <class HammingComputer>
267
- static size_t polysemous_inner_loop(
268
- const IndexPQ& index,
268
+ size_t polysemous_inner_loop(
269
+ const IndexPQ* index,
269
270
  const float* dis_table_qi,
270
271
  const uint8_t* q_code,
271
272
  size_t k,
272
273
  float* heap_dis,
273
274
  int64_t* heap_ids,
274
275
  int ht) {
275
- int M = index.pq.M;
276
- int code_size = index.pq.code_size;
277
- int ksub = index.pq.ksub;
278
- size_t ntotal = index.ntotal;
276
+ int M = index->pq.M;
277
+ int code_size = index->pq.code_size;
278
+ int ksub = index->pq.ksub;
279
+ size_t ntotal = index->ntotal;
279
280
 
280
- const uint8_t* b_code = index.codes.data();
281
+ const uint8_t* b_code = index->codes.data();
281
282
 
282
283
  size_t n_pass_i = 0;
283
284
 
@@ -305,6 +306,16 @@ static size_t polysemous_inner_loop(
305
306
  return n_pass_i;
306
307
  }
307
308
 
309
+ struct Run_polysemous_inner_loop {
310
+ using T = size_t;
311
+ template <class HammingComputer, class... Types>
312
+ size_t f(Types... args) {
313
+ return polysemous_inner_loop<HammingComputer>(args...);
314
+ }
315
+ };
316
+
317
+ } // anonymous namespace
318
+
308
319
  void IndexPQ::search_core_polysemous(
309
320
  idx_t n,
310
321
  const float* x,
@@ -321,22 +332,20 @@ void IndexPQ::search_core_polysemous(
321
332
  }
322
333
 
323
334
  // PQ distance tables
324
- float* dis_tables = new float[n * pq.ksub * pq.M];
325
- ScopeDeleter<float> del(dis_tables);
326
- pq.compute_distance_tables(n, x, dis_tables);
335
+ std::unique_ptr<float[]> dis_tables(new float[n * pq.ksub * pq.M]);
336
+ pq.compute_distance_tables(n, x, dis_tables.get());
327
337
 
328
338
  // Hamming embedding queries
329
- uint8_t* q_codes = new uint8_t[n * pq.code_size];
330
- ScopeDeleter<uint8_t> del2(q_codes);
339
+ std::unique_ptr<uint8_t[]> q_codes(new uint8_t[n * pq.code_size]);
331
340
 
332
341
  if (false) {
333
- pq.compute_codes(x, q_codes, n);
342
+ pq.compute_codes(x, q_codes.get(), n);
334
343
  } else {
335
344
  #pragma omp parallel for
336
345
  for (idx_t qi = 0; qi < n; qi++) {
337
346
  pq.compute_code_from_distance_table(
338
- dis_tables + qi * pq.M * pq.ksub,
339
- q_codes + qi * pq.code_size);
347
+ dis_tables.get() + qi * pq.M * pq.ksub,
348
+ q_codes.get() + qi * pq.code_size);
340
349
  }
341
350
  }
342
351
 
@@ -346,54 +355,33 @@ void IndexPQ::search_core_polysemous(
346
355
 
347
356
  #pragma omp parallel for reduction(+ : n_pass, bad_code_size)
348
357
  for (idx_t qi = 0; qi < n; qi++) {
349
- const uint8_t* q_code = q_codes + qi * pq.code_size;
358
+ const uint8_t* q_code = q_codes.get() + qi * pq.code_size;
350
359
 
351
- const float* dis_table_qi = dis_tables + qi * pq.M * pq.ksub;
360
+ const float* dis_table_qi = dis_tables.get() + qi * pq.M * pq.ksub;
352
361
 
353
362
  int64_t* heap_ids = labels + qi * k;
354
363
  float* heap_dis = distances + qi * k;
355
364
  maxheap_heapify(k, heap_dis, heap_ids);
356
365
 
357
366
  if (!generalized_hamming) {
358
- switch (pq.code_size) {
359
- #define DISPATCH(cs) \
360
- case cs: \
361
- n_pass += polysemous_inner_loop<HammingComputer##cs>( \
362
- *this, \
363
- dis_table_qi, \
364
- q_code, \
365
- k, \
366
- heap_dis, \
367
- heap_ids, \
368
- polysemous_ht); \
369
- break;
370
- DISPATCH(4)
371
- DISPATCH(8)
372
- DISPATCH(16)
373
- DISPATCH(32)
374
- DISPATCH(20)
375
- default:
376
- if (pq.code_size % 4 == 0) {
377
- n_pass += polysemous_inner_loop<HammingComputerDefault>(
378
- *this,
379
- dis_table_qi,
380
- q_code,
381
- k,
382
- heap_dis,
383
- heap_ids,
384
- polysemous_ht);
385
- } else {
386
- bad_code_size++;
387
- }
388
- break;
389
- }
390
- #undef DISPATCH
367
+ Run_polysemous_inner_loop r;
368
+ n_pass += dispatch_HammingComputer(
369
+ pq.code_size,
370
+ r,
371
+ this,
372
+ dis_table_qi,
373
+ q_code,
374
+ k,
375
+ heap_dis,
376
+ heap_ids,
377
+ polysemous_ht);
378
+
391
379
  } else { // generalized hamming
392
380
  switch (pq.code_size) {
393
381
  #define DISPATCH(cs) \
394
382
  case cs: \
395
383
  n_pass += polysemous_inner_loop<GenHammingComputer##cs>( \
396
- *this, \
384
+ this, \
397
385
  dis_table_qi, \
398
386
  q_code, \
399
387
  k, \
@@ -407,7 +395,7 @@ void IndexPQ::search_core_polysemous(
407
395
  default:
408
396
  if (pq.code_size % 8 == 0) {
409
397
  n_pass += polysemous_inner_loop<GenHammingComputerM8>(
410
- *this,
398
+ this,
411
399
  dis_table_qi,
412
400
  q_code,
413
401
  k,
@@ -450,12 +438,11 @@ void IndexPQ::sa_decode(idx_t n, const uint8_t* bytes, float* x) const {
450
438
 
451
439
  void IndexPQ::hamming_distance_table(idx_t n, const float* x, int32_t* dis)
452
440
  const {
453
- uint8_t* q_codes = new uint8_t[n * pq.code_size];
454
- ScopeDeleter<uint8_t> del(q_codes);
441
+ std::unique_ptr<uint8_t[]> q_codes(new uint8_t[n * pq.code_size]);
455
442
 
456
- pq.compute_codes(x, q_codes, n);
443
+ pq.compute_codes(x, q_codes.get(), n);
457
444
 
458
- hammings(q_codes, codes.data(), n, ntotal, pq.code_size, dis);
445
+ hammings(q_codes.get(), codes.data(), n, ntotal, pq.code_size, dis);
459
446
  }
460
447
 
461
448
  void IndexPQ::hamming_distance_histogram(
@@ -469,16 +456,15 @@ void IndexPQ::hamming_distance_histogram(
469
456
  FAISS_THROW_IF_NOT(pq.nbits == 8);
470
457
 
471
458
  // Hamming embedding queries
472
- uint8_t* q_codes = new uint8_t[n * pq.code_size];
473
- ScopeDeleter<uint8_t> del(q_codes);
474
- pq.compute_codes(x, q_codes, n);
459
+ std::unique_ptr<uint8_t[]> q_codes(new uint8_t[n * pq.code_size]);
460
+ pq.compute_codes(x, q_codes.get(), n);
475
461
 
476
462
  uint8_t* b_codes;
477
- ScopeDeleter<uint8_t> del_b_codes;
463
+ std::unique_ptr<uint8_t[]> del_b_codes;
478
464
 
479
465
  if (xb) {
480
466
  b_codes = new uint8_t[nb * pq.code_size];
481
- del_b_codes.set(b_codes);
467
+ del_b_codes.reset(b_codes);
482
468
  pq.compute_codes(xb, b_codes, nb);
483
469
  } else {
484
470
  nb = ntotal;
@@ -491,8 +477,7 @@ void IndexPQ::hamming_distance_histogram(
491
477
  #pragma omp parallel
492
478
  {
493
479
  std::vector<int64_t> histi(nbits + 1);
494
- hamdis_t* distances = new hamdis_t[nb * bs];
495
- ScopeDeleter<hamdis_t> del(distances);
480
+ std::unique_ptr<hamdis_t[]> distances(new hamdis_t[nb * bs]);
496
481
  #pragma omp for
497
482
  for (idx_t q0 = 0; q0 < n; q0 += bs) {
498
483
  // printf ("dis stats: %zd/%zd\n", q0, n);
@@ -501,12 +486,12 @@ void IndexPQ::hamming_distance_histogram(
501
486
  q1 = n;
502
487
 
503
488
  hammings(
504
- q_codes + q0 * pq.code_size,
489
+ q_codes.get() + q0 * pq.code_size,
505
490
  b_codes,
506
491
  q1 - q0,
507
492
  nb,
508
493
  pq.code_size,
509
- distances);
494
+ distances.get());
510
495
 
511
496
  for (size_t i = 0; i < nb * (q1 - q0); i++)
512
497
  histi[distances[i]]++;
@@ -639,7 +624,7 @@ struct SemiSortedArray {
639
624
  int N;
640
625
 
641
626
  // type of the heap: CMax = sort ascending
642
- typedef CMax<T, int> HC;
627
+ using HC = CMax<T, int>;
643
628
  std::vector<int> perm;
644
629
 
645
630
  int k; // k elements are sorted
@@ -733,7 +718,7 @@ struct MinSumK {
733
718
  * We use a heap to maintain a queue of sums, with the associated
734
719
  * terms involved in the sum.
735
720
  */
736
- typedef CMin<T, int64_t> HC;
721
+ using HC = CMin<T, int64_t>;
737
722
  size_t heap_capacity, heap_size;
738
723
  T* bh_val;
739
724
  int64_t* bh_ids;
@@ -827,7 +812,7 @@ struct MinSumK {
827
812
  // enqueue followers
828
813
  int64_t ii = ti;
829
814
  for (int m = 0; m < M; m++) {
830
- int64_t n = ii & ((1L << nbit) - 1);
815
+ int64_t n = ii & (((int64_t)1 << nbit) - 1);
831
816
  ii >>= nbit;
832
817
  if (n + 1 >= N)
833
818
  continue;
@@ -851,7 +836,7 @@ struct MinSumK {
851
836
  }
852
837
  int64_t ti = 0;
853
838
  for (int m = 0; m < M; m++) {
854
- int64_t n = ii & ((1L << nbit) - 1);
839
+ int64_t n = ii & (((int64_t)1 << nbit) - 1);
855
840
  ti += int64_t(ssx[m].get_ord(n)) << (nbit * m);
856
841
  ii >>= nbit;
857
842
  }
@@ -923,17 +908,16 @@ void MultiIndexQuantizer::search(
923
908
  return;
924
909
  }
925
910
 
926
- float* dis_tables = new float[n * pq.ksub * pq.M];
927
- ScopeDeleter<float> del(dis_tables);
911
+ std::unique_ptr<float[]> dis_tables(new float[n * pq.ksub * pq.M]);
928
912
 
929
- pq.compute_distance_tables(n, x, dis_tables);
913
+ pq.compute_distance_tables(n, x, dis_tables.get());
930
914
 
931
915
  if (k == 1) {
932
916
  // simple version that just finds the min in each table
933
917
 
934
918
  #pragma omp parallel for
935
919
  for (int i = 0; i < n; i++) {
936
- const float* dis_table = dis_tables + i * pq.ksub * pq.M;
920
+ const float* dis_table = dis_tables.get() + i * pq.ksub * pq.M;
937
921
  float dis = 0;
938
922
  idx_t label = 0;
939
923
 
@@ -963,7 +947,7 @@ void MultiIndexQuantizer::search(
963
947
  k, pq.M, pq.nbits, pq.ksub);
964
948
  #pragma omp for
965
949
  for (int i = 0; i < n; i++) {
966
- msk.run(dis_tables + i * pq.ksub * pq.M,
950
+ msk.run(dis_tables.get() + i * pq.ksub * pq.M,
967
951
  pq.ksub,
968
952
  distances + i * k,
969
953
  labels + i * k);
@@ -975,7 +959,7 @@ void MultiIndexQuantizer::search(
975
959
  void MultiIndexQuantizer::reconstruct(idx_t key, float* recons) const {
976
960
  int64_t jj = key;
977
961
  for (int m = 0; m < pq.M; m++) {
978
- int64_t n = jj & ((1L << pq.nbits) - 1);
962
+ int64_t n = jj & (((int64_t)1 << pq.nbits) - 1);
979
963
  jj >>= pq.nbits;
980
964
  memcpy(recons, pq.get_centroids(m, n), sizeof(recons[0]) * pq.dsub);
981
965
  recons += pq.dsub;
@@ -1107,7 +1091,7 @@ void MultiIndexQuantizer2::search(
1107
1091
 
1108
1092
  const idx_t* idmap0 = sub_ids.data() + i * k2;
1109
1093
  int64_t ld_idmap = k2 * n;
1110
- int64_t mask1 = ksub - 1L;
1094
+ int64_t mask1 = ksub - (int64_t)1;
1111
1095
 
1112
1096
  for (int k = 0; k < K; k++) {
1113
1097
  const idx_t* idmap = idmap0;
@@ -31,10 +31,7 @@ struct IndexPQ : IndexFlatCodes {
31
31
  * @param M number of subquantizers
32
32
  * @param nbits number of bit per subvector index
33
33
  */
34
- IndexPQ(int d, ///< dimensionality of the input vectors
35
- size_t M, ///< number of subquantizers
36
- size_t nbits, ///< number of bit per subvector index
37
- MetricType metric = METRIC_L2);
34
+ IndexPQ(int d, size_t M, size_t nbits, MetricType metric = METRIC_L2);
38
35
 
39
36
  IndexPQ();
40
37
 
@@ -7,8 +7,8 @@
7
7
 
8
8
  #include <faiss/IndexPQFastScan.h>
9
9
 
10
- #include <limits.h>
11
10
  #include <cassert>
11
+ #include <climits>
12
12
  #include <memory>
13
13
 
14
14
  #include <omp.h>