faiss 0.3.0 → 0.3.2

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