faiss 0.2.3 → 0.2.5

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 (189) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +23 -21
  5. data/ext/faiss/extconf.rb +11 -0
  6. data/ext/faiss/index.cpp +4 -4
  7. data/ext/faiss/index_binary.cpp +6 -6
  8. data/ext/faiss/product_quantizer.cpp +4 -4
  9. data/lib/faiss/version.rb +1 -1
  10. data/vendor/faiss/faiss/AutoTune.cpp +13 -0
  11. data/vendor/faiss/faiss/Clustering.cpp +32 -0
  12. data/vendor/faiss/faiss/Clustering.h +14 -0
  13. data/vendor/faiss/faiss/IVFlib.cpp +101 -2
  14. data/vendor/faiss/faiss/IVFlib.h +26 -2
  15. data/vendor/faiss/faiss/Index.cpp +36 -3
  16. data/vendor/faiss/faiss/Index.h +43 -6
  17. data/vendor/faiss/faiss/Index2Layer.cpp +24 -93
  18. data/vendor/faiss/faiss/Index2Layer.h +8 -17
  19. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +610 -0
  20. data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +253 -0
  21. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +299 -0
  22. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +199 -0
  23. data/vendor/faiss/faiss/IndexBinary.cpp +20 -4
  24. data/vendor/faiss/faiss/IndexBinary.h +18 -3
  25. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +9 -2
  26. data/vendor/faiss/faiss/IndexBinaryFlat.h +4 -2
  27. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -1
  28. data/vendor/faiss/faiss/IndexBinaryFromFloat.h +2 -1
  29. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +5 -1
  30. data/vendor/faiss/faiss/IndexBinaryHNSW.h +2 -1
  31. data/vendor/faiss/faiss/IndexBinaryHash.cpp +17 -4
  32. data/vendor/faiss/faiss/IndexBinaryHash.h +8 -4
  33. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +28 -13
  34. data/vendor/faiss/faiss/IndexBinaryIVF.h +10 -7
  35. data/vendor/faiss/faiss/IndexFastScan.cpp +626 -0
  36. data/vendor/faiss/faiss/IndexFastScan.h +145 -0
  37. data/vendor/faiss/faiss/IndexFlat.cpp +52 -69
  38. data/vendor/faiss/faiss/IndexFlat.h +16 -19
  39. data/vendor/faiss/faiss/IndexFlatCodes.cpp +101 -0
  40. data/vendor/faiss/faiss/IndexFlatCodes.h +59 -0
  41. data/vendor/faiss/faiss/IndexHNSW.cpp +66 -138
  42. data/vendor/faiss/faiss/IndexHNSW.h +4 -2
  43. data/vendor/faiss/faiss/IndexIDMap.cpp +247 -0
  44. data/vendor/faiss/faiss/IndexIDMap.h +107 -0
  45. data/vendor/faiss/faiss/IndexIVF.cpp +200 -40
  46. data/vendor/faiss/faiss/IndexIVF.h +59 -22
  47. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +393 -0
  48. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +183 -0
  49. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +590 -0
  50. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +171 -0
  51. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +1290 -0
  52. data/vendor/faiss/faiss/IndexIVFFastScan.h +213 -0
  53. data/vendor/faiss/faiss/IndexIVFFlat.cpp +43 -26
  54. data/vendor/faiss/faiss/IndexIVFFlat.h +4 -2
  55. data/vendor/faiss/faiss/IndexIVFPQ.cpp +238 -53
  56. data/vendor/faiss/faiss/IndexIVFPQ.h +6 -2
  57. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +23 -852
  58. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +7 -112
  59. data/vendor/faiss/faiss/IndexIVFPQR.cpp +3 -3
  60. data/vendor/faiss/faiss/IndexIVFPQR.h +1 -1
  61. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +63 -40
  62. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +23 -7
  63. data/vendor/faiss/faiss/IndexLSH.cpp +8 -32
  64. data/vendor/faiss/faiss/IndexLSH.h +4 -16
  65. data/vendor/faiss/faiss/IndexLattice.cpp +7 -1
  66. data/vendor/faiss/faiss/IndexLattice.h +3 -1
  67. data/vendor/faiss/faiss/IndexNNDescent.cpp +4 -5
  68. data/vendor/faiss/faiss/IndexNNDescent.h +2 -1
  69. data/vendor/faiss/faiss/IndexNSG.cpp +37 -5
  70. data/vendor/faiss/faiss/IndexNSG.h +25 -1
  71. data/vendor/faiss/faiss/IndexPQ.cpp +108 -120
  72. data/vendor/faiss/faiss/IndexPQ.h +21 -22
  73. data/vendor/faiss/faiss/IndexPQFastScan.cpp +15 -450
  74. data/vendor/faiss/faiss/IndexPQFastScan.h +15 -78
  75. data/vendor/faiss/faiss/IndexPreTransform.cpp +47 -8
  76. data/vendor/faiss/faiss/IndexPreTransform.h +15 -3
  77. data/vendor/faiss/faiss/IndexRefine.cpp +36 -4
  78. data/vendor/faiss/faiss/IndexRefine.h +14 -2
  79. data/vendor/faiss/faiss/IndexReplicas.cpp +4 -2
  80. data/vendor/faiss/faiss/IndexReplicas.h +2 -1
  81. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +438 -0
  82. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +92 -0
  83. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +28 -43
  84. data/vendor/faiss/faiss/IndexScalarQuantizer.h +8 -23
  85. data/vendor/faiss/faiss/IndexShards.cpp +4 -1
  86. data/vendor/faiss/faiss/IndexShards.h +2 -1
  87. data/vendor/faiss/faiss/MetaIndexes.cpp +5 -178
  88. data/vendor/faiss/faiss/MetaIndexes.h +3 -81
  89. data/vendor/faiss/faiss/VectorTransform.cpp +45 -1
  90. data/vendor/faiss/faiss/VectorTransform.h +25 -4
  91. data/vendor/faiss/faiss/clone_index.cpp +26 -3
  92. data/vendor/faiss/faiss/clone_index.h +3 -0
  93. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +300 -0
  94. data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +24 -0
  95. data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +195 -0
  96. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +2058 -0
  97. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +408 -0
  98. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +2147 -0
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +460 -0
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +465 -0
  101. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +1618 -0
  102. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +251 -0
  103. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +1452 -0
  104. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +1 -0
  105. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +2 -6
  106. data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +60 -0
  107. data/vendor/faiss/faiss/gpu/GpuIndex.h +28 -4
  108. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +2 -1
  109. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +10 -8
  110. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +75 -14
  111. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +19 -32
  112. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -31
  113. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +22 -28
  114. data/vendor/faiss/faiss/gpu/GpuResources.cpp +14 -0
  115. data/vendor/faiss/faiss/gpu/GpuResources.h +16 -3
  116. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +3 -3
  117. data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +32 -0
  118. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +1 -0
  119. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +311 -75
  120. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +10 -0
  121. data/vendor/faiss/faiss/gpu/test/TestUtils.h +3 -0
  122. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +2 -2
  123. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +5 -4
  124. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +331 -29
  125. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +110 -19
  126. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +0 -54
  127. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +0 -76
  128. data/vendor/faiss/faiss/impl/DistanceComputer.h +64 -0
  129. data/vendor/faiss/faiss/impl/HNSW.cpp +133 -32
  130. data/vendor/faiss/faiss/impl/HNSW.h +19 -16
  131. data/vendor/faiss/faiss/impl/IDSelector.cpp +125 -0
  132. data/vendor/faiss/faiss/impl/IDSelector.h +135 -0
  133. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +378 -217
  134. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +106 -29
  135. data/vendor/faiss/faiss/impl/LookupTableScaler.h +77 -0
  136. data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -0
  137. data/vendor/faiss/faiss/impl/NSG.cpp +1 -4
  138. data/vendor/faiss/faiss/impl/NSG.h +1 -1
  139. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +383 -0
  140. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +154 -0
  141. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +225 -145
  142. data/vendor/faiss/faiss/impl/ProductQuantizer.h +29 -10
  143. data/vendor/faiss/faiss/impl/Quantizer.h +43 -0
  144. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +521 -55
  145. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +94 -16
  146. data/vendor/faiss/faiss/impl/ResultHandler.h +96 -0
  147. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +108 -191
  148. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +18 -18
  149. data/vendor/faiss/faiss/impl/index_read.cpp +338 -24
  150. data/vendor/faiss/faiss/impl/index_write.cpp +300 -18
  151. data/vendor/faiss/faiss/impl/io.cpp +1 -1
  152. data/vendor/faiss/faiss/impl/io_macros.h +20 -0
  153. data/vendor/faiss/faiss/impl/kmeans1d.cpp +303 -0
  154. data/vendor/faiss/faiss/impl/kmeans1d.h +48 -0
  155. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +56 -16
  156. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +25 -8
  157. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +66 -25
  158. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +75 -27
  159. data/vendor/faiss/faiss/index_factory.cpp +772 -412
  160. data/vendor/faiss/faiss/index_factory.h +3 -0
  161. data/vendor/faiss/faiss/index_io.h +5 -0
  162. data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -0
  163. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +4 -1
  164. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +2 -1
  165. data/vendor/faiss/faiss/python/python_callbacks.cpp +27 -0
  166. data/vendor/faiss/faiss/python/python_callbacks.h +15 -0
  167. data/vendor/faiss/faiss/utils/Heap.h +31 -15
  168. data/vendor/faiss/faiss/utils/distances.cpp +384 -58
  169. data/vendor/faiss/faiss/utils/distances.h +149 -18
  170. data/vendor/faiss/faiss/utils/distances_simd.cpp +776 -6
  171. data/vendor/faiss/faiss/utils/extra_distances.cpp +12 -7
  172. data/vendor/faiss/faiss/utils/extra_distances.h +3 -1
  173. data/vendor/faiss/faiss/utils/fp16-fp16c.h +21 -0
  174. data/vendor/faiss/faiss/utils/fp16-inl.h +101 -0
  175. data/vendor/faiss/faiss/utils/fp16.h +11 -0
  176. data/vendor/faiss/faiss/utils/hamming-inl.h +54 -0
  177. data/vendor/faiss/faiss/utils/hamming.cpp +0 -48
  178. data/vendor/faiss/faiss/utils/ordered_key_value.h +10 -0
  179. data/vendor/faiss/faiss/utils/quantize_lut.cpp +62 -0
  180. data/vendor/faiss/faiss/utils/quantize_lut.h +20 -0
  181. data/vendor/faiss/faiss/utils/random.cpp +53 -0
  182. data/vendor/faiss/faiss/utils/random.h +5 -0
  183. data/vendor/faiss/faiss/utils/simdlib_avx2.h +4 -0
  184. data/vendor/faiss/faiss/utils/simdlib_emulated.h +6 -1
  185. data/vendor/faiss/faiss/utils/simdlib_neon.h +7 -2
  186. data/vendor/faiss/faiss/utils/utils.h +1 -1
  187. metadata +46 -5
  188. data/vendor/faiss/faiss/IndexResidual.cpp +0 -291
  189. data/vendor/faiss/faiss/IndexResidual.h +0 -152
@@ -13,26 +13,19 @@
13
13
  #include <stdint.h>
14
14
  #include <vector>
15
15
 
16
+ #include <faiss/IndexFlatCodes.h>
16
17
  #include <faiss/IndexIVF.h>
17
18
  #include <faiss/impl/ScalarQuantizer.h>
18
19
 
19
20
  namespace faiss {
20
21
 
21
22
  /**
22
- * The uniform quantizer has a range [vmin, vmax]. The range can be
23
- * the same for all dimensions (uniform) or specific per dimension
24
- * (default).
23
+ * Flat index built on a scalar quantizer.
25
24
  */
26
-
27
- struct IndexScalarQuantizer : Index {
25
+ struct IndexScalarQuantizer : IndexFlatCodes {
28
26
  /// Used to encode the vectors
29
27
  ScalarQuantizer sq;
30
28
 
31
- /// Codes. Size ntotal * pq.code_size
32
- std::vector<uint8_t> codes;
33
-
34
- size_t code_size;
35
-
36
29
  /** Constructor.
37
30
  *
38
31
  * @param d dimensionality of the input vectors
@@ -48,26 +41,17 @@ struct IndexScalarQuantizer : Index {
48
41
 
49
42
  void train(idx_t n, const float* x) override;
50
43
 
51
- void add(idx_t n, const float* x) override;
52
-
53
44
  void search(
54
45
  idx_t n,
55
46
  const float* x,
56
47
  idx_t k,
57
48
  float* distances,
58
- idx_t* labels) const override;
49
+ idx_t* labels,
50
+ const SearchParameters* params = nullptr) const override;
59
51
 
60
- void reset() override;
61
-
62
- void reconstruct_n(idx_t i0, idx_t ni, float* recons) const override;
63
-
64
- void reconstruct(idx_t key, float* recons) const override;
65
-
66
- DistanceComputer* get_distance_computer() const override;
52
+ FlatCodesDistanceComputer* get_FlatCodesDistanceComputer() const override;
67
53
 
68
54
  /* standalone codec interface */
69
- size_t sa_code_size() const override;
70
-
71
55
  void sa_encode(idx_t n, const float* x, uint8_t* bytes) const override;
72
56
 
73
57
  void sa_decode(idx_t n, const uint8_t* bytes, float* x) const override;
@@ -109,7 +93,8 @@ struct IndexIVFScalarQuantizer : IndexIVF {
109
93
  const idx_t* precomputed_idx) override;
110
94
 
111
95
  InvertedListScanner* get_InvertedListScanner(
112
- bool store_pairs) const override;
96
+ bool store_pairs,
97
+ const IDSelector* sel) const override;
113
98
 
114
99
  void reconstruct_from_offset(int64_t list_no, int64_t offset, float* recons)
115
100
  const override;
@@ -288,7 +288,10 @@ void IndexShardsTemplate<IndexT>::search(
288
288
  const component_t* x,
289
289
  idx_t k,
290
290
  distance_t* distances,
291
- idx_t* labels) const {
291
+ idx_t* labels,
292
+ const SearchParameters* params) const {
293
+ FAISS_THROW_IF_NOT_MSG(
294
+ !params, "search params not supported for this index");
292
295
  FAISS_THROW_IF_NOT(k > 0);
293
296
 
294
297
  long nshard = this->count();
@@ -87,7 +87,8 @@ struct IndexShardsTemplate : public ThreadedIndex<IndexT> {
87
87
  const component_t* x,
88
88
  idx_t k,
89
89
  distance_t* distances,
90
- idx_t* labels) const override;
90
+ idx_t* labels,
91
+ const SearchParameters* params = nullptr) const override;
91
92
 
92
93
  void train(idx_t n, const component_t* x) override;
93
94
 
@@ -16,188 +16,12 @@
16
16
 
17
17
  #include <faiss/impl/AuxIndexStructures.h>
18
18
  #include <faiss/impl/FaissAssert.h>
19
+ #include <faiss/impl/IDSelector.h>
19
20
  #include <faiss/utils/Heap.h>
20
21
  #include <faiss/utils/WorkerThread.h>
21
22
 
22
23
  namespace faiss {
23
24
 
24
- namespace {} // namespace
25
-
26
- /*****************************************************
27
- * IndexIDMap implementation
28
- *******************************************************/
29
-
30
- template <typename IndexT>
31
- IndexIDMapTemplate<IndexT>::IndexIDMapTemplate(IndexT* index)
32
- : index(index), own_fields(false) {
33
- FAISS_THROW_IF_NOT_MSG(index->ntotal == 0, "index must be empty on input");
34
- this->is_trained = index->is_trained;
35
- this->metric_type = index->metric_type;
36
- this->verbose = index->verbose;
37
- this->d = index->d;
38
- }
39
-
40
- template <typename IndexT>
41
- void IndexIDMapTemplate<IndexT>::add(
42
- idx_t,
43
- const typename IndexT::component_t*) {
44
- FAISS_THROW_MSG(
45
- "add does not make sense with IndexIDMap, "
46
- "use add_with_ids");
47
- }
48
-
49
- template <typename IndexT>
50
- void IndexIDMapTemplate<IndexT>::train(
51
- idx_t n,
52
- const typename IndexT::component_t* x) {
53
- index->train(n, x);
54
- this->is_trained = index->is_trained;
55
- }
56
-
57
- template <typename IndexT>
58
- void IndexIDMapTemplate<IndexT>::reset() {
59
- index->reset();
60
- id_map.clear();
61
- this->ntotal = 0;
62
- }
63
-
64
- template <typename IndexT>
65
- void IndexIDMapTemplate<IndexT>::add_with_ids(
66
- idx_t n,
67
- const typename IndexT::component_t* x,
68
- const typename IndexT::idx_t* xids) {
69
- index->add(n, x);
70
- for (idx_t i = 0; i < n; i++)
71
- id_map.push_back(xids[i]);
72
- this->ntotal = index->ntotal;
73
- }
74
-
75
- template <typename IndexT>
76
- void IndexIDMapTemplate<IndexT>::search(
77
- idx_t n,
78
- const typename IndexT::component_t* x,
79
- idx_t k,
80
- typename IndexT::distance_t* distances,
81
- typename IndexT::idx_t* labels) const {
82
- index->search(n, x, k, distances, labels);
83
- idx_t* li = labels;
84
- #pragma omp parallel for
85
- for (idx_t i = 0; i < n * k; i++) {
86
- li[i] = li[i] < 0 ? li[i] : id_map[li[i]];
87
- }
88
- }
89
-
90
- template <typename IndexT>
91
- void IndexIDMapTemplate<IndexT>::range_search(
92
- typename IndexT::idx_t n,
93
- const typename IndexT::component_t* x,
94
- typename IndexT::distance_t radius,
95
- RangeSearchResult* result) const {
96
- index->range_search(n, x, radius, result);
97
- #pragma omp parallel for
98
- for (idx_t i = 0; i < result->lims[result->nq]; i++) {
99
- result->labels[i] = result->labels[i] < 0 ? result->labels[i]
100
- : id_map[result->labels[i]];
101
- }
102
- }
103
-
104
- namespace {
105
-
106
- struct IDTranslatedSelector : IDSelector {
107
- const std::vector<int64_t>& id_map;
108
- const IDSelector& sel;
109
- IDTranslatedSelector(
110
- const std::vector<int64_t>& id_map,
111
- const IDSelector& sel)
112
- : id_map(id_map), sel(sel) {}
113
- bool is_member(idx_t id) const override {
114
- return sel.is_member(id_map[id]);
115
- }
116
- };
117
-
118
- } // namespace
119
-
120
- template <typename IndexT>
121
- size_t IndexIDMapTemplate<IndexT>::remove_ids(const IDSelector& sel) {
122
- // remove in sub-index first
123
- IDTranslatedSelector sel2(id_map, sel);
124
- size_t nremove = index->remove_ids(sel2);
125
-
126
- int64_t j = 0;
127
- for (idx_t i = 0; i < this->ntotal; i++) {
128
- if (sel.is_member(id_map[i])) {
129
- // remove
130
- } else {
131
- id_map[j] = id_map[i];
132
- j++;
133
- }
134
- }
135
- FAISS_ASSERT(j == index->ntotal);
136
- this->ntotal = j;
137
- id_map.resize(this->ntotal);
138
- return nremove;
139
- }
140
-
141
- template <typename IndexT>
142
- IndexIDMapTemplate<IndexT>::~IndexIDMapTemplate() {
143
- if (own_fields)
144
- delete index;
145
- }
146
-
147
- /*****************************************************
148
- * IndexIDMap2 implementation
149
- *******************************************************/
150
-
151
- template <typename IndexT>
152
- IndexIDMap2Template<IndexT>::IndexIDMap2Template(IndexT* index)
153
- : IndexIDMapTemplate<IndexT>(index) {}
154
-
155
- template <typename IndexT>
156
- void IndexIDMap2Template<IndexT>::add_with_ids(
157
- idx_t n,
158
- const typename IndexT::component_t* x,
159
- const typename IndexT::idx_t* xids) {
160
- size_t prev_ntotal = this->ntotal;
161
- IndexIDMapTemplate<IndexT>::add_with_ids(n, x, xids);
162
- for (size_t i = prev_ntotal; i < this->ntotal; i++) {
163
- rev_map[this->id_map[i]] = i;
164
- }
165
- }
166
-
167
- template <typename IndexT>
168
- void IndexIDMap2Template<IndexT>::construct_rev_map() {
169
- rev_map.clear();
170
- for (size_t i = 0; i < this->ntotal; i++) {
171
- rev_map[this->id_map[i]] = i;
172
- }
173
- }
174
-
175
- template <typename IndexT>
176
- size_t IndexIDMap2Template<IndexT>::remove_ids(const IDSelector& sel) {
177
- // This is quite inefficient
178
- size_t nremove = IndexIDMapTemplate<IndexT>::remove_ids(sel);
179
- construct_rev_map();
180
- return nremove;
181
- }
182
-
183
- template <typename IndexT>
184
- void IndexIDMap2Template<IndexT>::reconstruct(
185
- idx_t key,
186
- typename IndexT::component_t* recons) const {
187
- try {
188
- this->index->reconstruct(rev_map.at(key), recons);
189
- } catch (const std::out_of_range& e) {
190
- FAISS_THROW_FMT("key %" PRId64 " not found", key);
191
- }
192
- }
193
-
194
- // explicit template instantiations
195
-
196
- template struct IndexIDMapTemplate<Index>;
197
- template struct IndexIDMapTemplate<IndexBinary>;
198
- template struct IndexIDMap2Template<Index>;
199
- template struct IndexIDMap2Template<IndexBinary>;
200
-
201
25
  /*****************************************************
202
26
  * IndexSplitVectors implementation
203
27
  *******************************************************/
@@ -235,7 +59,10 @@ void IndexSplitVectors::search(
235
59
  const float* x,
236
60
  idx_t k,
237
61
  float* distances,
238
- idx_t* labels) const {
62
+ idx_t* labels,
63
+ const SearchParameters* params) const {
64
+ FAISS_THROW_IF_NOT_MSG(
65
+ !params, "search params not supported for this index");
239
66
  FAISS_THROW_IF_NOT_MSG(k == 1, "search implemented only for k=1");
240
67
  FAISS_THROW_IF_NOT_MSG(
241
68
  sum_d == d, "not enough indexes compared to # dimensions");
@@ -11,92 +11,13 @@
11
11
  #define META_INDEXES_H
12
12
 
13
13
  #include <faiss/Index.h>
14
+ #include <faiss/IndexIDMap.h>
14
15
  #include <faiss/IndexReplicas.h>
15
16
  #include <faiss/IndexShards.h>
16
- #include <unordered_map>
17
17
  #include <vector>
18
18
 
19
19
  namespace faiss {
20
20
 
21
- /** Index that translates search results to ids */
22
- template <typename IndexT>
23
- struct IndexIDMapTemplate : IndexT {
24
- using idx_t = typename IndexT::idx_t;
25
- using component_t = typename IndexT::component_t;
26
- using distance_t = typename IndexT::distance_t;
27
-
28
- IndexT* index; ///! the sub-index
29
- bool own_fields; ///! whether pointers are deleted in destructo
30
- std::vector<idx_t> id_map;
31
-
32
- explicit IndexIDMapTemplate(IndexT* index);
33
-
34
- /// @param xids if non-null, ids to store for the vectors (size n)
35
- void add_with_ids(idx_t n, const component_t* x, const idx_t* xids)
36
- override;
37
-
38
- /// this will fail. Use add_with_ids
39
- void add(idx_t n, const component_t* x) override;
40
-
41
- void search(
42
- idx_t n,
43
- const component_t* x,
44
- idx_t k,
45
- distance_t* distances,
46
- idx_t* labels) const override;
47
-
48
- void train(idx_t n, const component_t* x) override;
49
-
50
- void reset() override;
51
-
52
- /// remove ids adapted to IndexFlat
53
- size_t remove_ids(const IDSelector& sel) override;
54
-
55
- void range_search(
56
- idx_t n,
57
- const component_t* x,
58
- distance_t radius,
59
- RangeSearchResult* result) const override;
60
-
61
- ~IndexIDMapTemplate() override;
62
- IndexIDMapTemplate() {
63
- own_fields = false;
64
- index = nullptr;
65
- }
66
- };
67
-
68
- using IndexIDMap = IndexIDMapTemplate<Index>;
69
- using IndexBinaryIDMap = IndexIDMapTemplate<IndexBinary>;
70
-
71
- /** same as IndexIDMap but also provides an efficient reconstruction
72
- * implementation via a 2-way index */
73
- template <typename IndexT>
74
- struct IndexIDMap2Template : IndexIDMapTemplate<IndexT> {
75
- using idx_t = typename IndexT::idx_t;
76
- using component_t = typename IndexT::component_t;
77
- using distance_t = typename IndexT::distance_t;
78
-
79
- std::unordered_map<idx_t, idx_t> rev_map;
80
-
81
- explicit IndexIDMap2Template(IndexT* index);
82
-
83
- /// make the rev_map from scratch
84
- void construct_rev_map();
85
-
86
- void add_with_ids(idx_t n, const component_t* x, const idx_t* xids)
87
- override;
88
-
89
- size_t remove_ids(const IDSelector& sel) override;
90
-
91
- void reconstruct(idx_t key, component_t* recons) const override;
92
-
93
- ~IndexIDMap2Template() override {}
94
- IndexIDMap2Template() {}
95
- };
96
-
97
- using IndexIDMap2 = IndexIDMap2Template<Index>;
98
- using IndexBinaryIDMap2 = IndexIDMap2Template<IndexBinary>;
99
-
100
21
  /** splits input vectors in segments and assigns each segment to a sub-index
101
22
  * used to distribute a MultiIndexQuantizer
102
23
  */
@@ -118,7 +39,8 @@ struct IndexSplitVectors : Index {
118
39
  const float* x,
119
40
  idx_t k,
120
41
  float* distances,
121
- idx_t* labels) const override;
42
+ idx_t* labels,
43
+ const SearchParameters* params = nullptr) const override;
122
44
 
123
45
  void train(idx_t n, const float* x) override;
124
46
 
@@ -149,6 +149,10 @@ void VectorTransform::reverse_transform(idx_t, const float*, float*) const {
149
149
  FAISS_THROW_MSG("reverse transform not implemented");
150
150
  }
151
151
 
152
+ void VectorTransform::check_identical(const VectorTransform& other) const {
153
+ FAISS_THROW_IF_NOT(other.d_in == d_in && other.d_in == d_in);
154
+ }
155
+
152
156
  /*********************************************
153
157
  * LinearTransform
154
158
  *********************************************/
@@ -308,6 +312,13 @@ void LinearTransform::print_if_verbose(
308
312
  printf("]\n");
309
313
  }
310
314
 
315
+ void LinearTransform::check_identical(const VectorTransform& other_in) const {
316
+ VectorTransform::check_identical(other_in);
317
+ auto other = dynamic_cast<const LinearTransform*>(&other_in);
318
+ FAISS_THROW_IF_NOT(other);
319
+ FAISS_THROW_IF_NOT(other->A == A && other->b == b);
320
+ }
321
+
311
322
  /*********************************************
312
323
  * RandomRotationMatrix
313
324
  *********************************************/
@@ -357,6 +368,7 @@ PCAMatrix::PCAMatrix(
357
368
  is_trained = false;
358
369
  max_points_per_d = 1000;
359
370
  balanced_bins = 0;
371
+ epsilon = 0;
360
372
  }
361
373
 
362
374
  namespace {
@@ -620,7 +632,7 @@ void PCAMatrix::prepare_Ab() {
620
632
  if (eigen_power != 0) {
621
633
  float* ai = A.data();
622
634
  for (int i = 0; i < d_out; i++) {
623
- float factor = pow(eigenvalues[i], eigen_power);
635
+ float factor = pow(eigenvalues[i] + epsilon, eigen_power);
624
636
  for (int j = 0; j < d_in; j++)
625
637
  *ai++ *= factor;
626
638
  }
@@ -965,6 +977,14 @@ void ITQTransform::apply_noalloc(Index::idx_t n, const float* x, float* xt)
965
977
  pca_then_itq.apply_noalloc(n, x_norm.get(), xt);
966
978
  }
967
979
 
980
+ void ITQTransform::check_identical(const VectorTransform& other_in) const {
981
+ VectorTransform::check_identical(other_in);
982
+ auto other = dynamic_cast<const ITQTransform*>(&other_in);
983
+ FAISS_THROW_IF_NOT(other);
984
+ pca_then_itq.check_identical(other->pca_then_itq);
985
+ FAISS_THROW_IF_NOT(other->mean == mean);
986
+ }
987
+
968
988
  /*********************************************
969
989
  * OPQMatrix
970
990
  *********************************************/
@@ -1225,6 +1245,14 @@ void NormalizationTransform::reverse_transform(
1225
1245
  memcpy(x, xt, sizeof(xt[0]) * n * d_in);
1226
1246
  }
1227
1247
 
1248
+ void NormalizationTransform::check_identical(
1249
+ const VectorTransform& other_in) const {
1250
+ VectorTransform::check_identical(other_in);
1251
+ auto other = dynamic_cast<const NormalizationTransform*>(&other_in);
1252
+ FAISS_THROW_IF_NOT(other);
1253
+ FAISS_THROW_IF_NOT(other->norm == norm);
1254
+ }
1255
+
1228
1256
  /*********************************************
1229
1257
  * CenteringTransform
1230
1258
  *********************************************/
@@ -1270,6 +1298,14 @@ void CenteringTransform::reverse_transform(idx_t n, const float* xt, float* x)
1270
1298
  }
1271
1299
  }
1272
1300
 
1301
+ void CenteringTransform::check_identical(
1302
+ const VectorTransform& other_in) const {
1303
+ VectorTransform::check_identical(other_in);
1304
+ auto other = dynamic_cast<const CenteringTransform*>(&other_in);
1305
+ FAISS_THROW_IF_NOT(other);
1306
+ FAISS_THROW_IF_NOT(other->mean == mean);
1307
+ }
1308
+
1273
1309
  /*********************************************
1274
1310
  * RemapDimensionsTransform
1275
1311
  *********************************************/
@@ -1334,3 +1370,11 @@ void RemapDimensionsTransform::reverse_transform(
1334
1370
  xt += d_out;
1335
1371
  }
1336
1372
  }
1373
+
1374
+ void RemapDimensionsTransform::check_identical(
1375
+ const VectorTransform& other_in) const {
1376
+ VectorTransform::check_identical(other_in);
1377
+ auto other = dynamic_cast<const RemapDimensionsTransform*>(&other_in);
1378
+ FAISS_THROW_IF_NOT(other);
1379
+ FAISS_THROW_IF_NOT(other->map == map);
1380
+ }
@@ -43,19 +43,27 @@ struct VectorTransform {
43
43
  */
44
44
  virtual void train(idx_t n, const float* x);
45
45
 
46
- /** apply the random rotation, return new allocated matrix
47
- * @param x size n * d_in
48
- * @return size n * d_out
46
+ /** apply the transformation and return the result in an allocated pointer
47
+ * @param n number of vectors to transform
48
+ * @param x input vectors, size n * d_in
49
+ * @return output vectors, size n * d_out
49
50
  */
50
51
  float* apply(idx_t n, const float* x) const;
51
52
 
52
- /// same as apply, but result is pre-allocated
53
+ /** apply the transformation and return the result in a provided matrix
54
+ * @param n number of vectors to transform
55
+ * @param x input vectors, size n * d_in
56
+ * @param xt output vectors, size n * d_out
57
+ */
53
58
  virtual void apply_noalloc(idx_t n, const float* x, float* xt) const = 0;
54
59
 
55
60
  /// reverse transformation. May not be implemented or may return
56
61
  /// approximate result
57
62
  virtual void reverse_transform(idx_t n, const float* xt, float* x) const;
58
63
 
64
+ // check that the two transforms are identical (to merge indexes)
65
+ virtual void check_identical(const VectorTransform& other) const = 0;
66
+
59
67
  virtual ~VectorTransform() {}
60
68
  };
61
69
 
@@ -100,6 +108,8 @@ struct LinearTransform : VectorTransform {
100
108
  int n,
101
109
  int d) const;
102
110
 
111
+ void check_identical(const VectorTransform& other) const override;
112
+
103
113
  ~LinearTransform() override {}
104
114
  };
105
115
 
@@ -129,6 +139,9 @@ struct PCAMatrix : LinearTransform {
129
139
  */
130
140
  float eigen_power;
131
141
 
142
+ /// value added to eigenvalues to avoid division by 0 when whitening
143
+ float epsilon;
144
+
132
145
  /// random rotation after PCA
133
146
  bool random_rotation;
134
147
 
@@ -204,6 +217,8 @@ struct ITQTransform : VectorTransform {
204
217
  void train(idx_t n, const float* x) override;
205
218
 
206
219
  void apply_noalloc(idx_t n, const float* x, float* xt) const override;
220
+
221
+ void check_identical(const VectorTransform& other) const override;
207
222
  };
208
223
 
209
224
  struct ProductQuantizer;
@@ -257,6 +272,8 @@ struct RemapDimensionsTransform : VectorTransform {
257
272
  void reverse_transform(idx_t n, const float* xt, float* x) const override;
258
273
 
259
274
  RemapDimensionsTransform() {}
275
+
276
+ void check_identical(const VectorTransform& other) const override;
260
277
  };
261
278
 
262
279
  /** per-vector normalization */
@@ -270,6 +287,8 @@ struct NormalizationTransform : VectorTransform {
270
287
 
271
288
  /// Identity transform since norm is not revertible
272
289
  void reverse_transform(idx_t n, const float* xt, float* x) const override;
290
+
291
+ void check_identical(const VectorTransform& other) const override;
273
292
  };
274
293
 
275
294
  /** Subtract the mean of each component from the vectors. */
@@ -287,6 +306,8 @@ struct CenteringTransform : VectorTransform {
287
306
 
288
307
  /// add the mean
289
308
  void reverse_transform(idx_t n, const float* xt, float* x) const override;
309
+
310
+ void check_identical(const VectorTransform& other) const override;
290
311
  };
291
312
 
292
313
  } // namespace faiss
@@ -15,6 +15,7 @@
15
15
  #include <faiss/impl/FaissAssert.h>
16
16
 
17
17
  #include <faiss/Index2Layer.h>
18
+ #include <faiss/IndexAdditiveQuantizer.h>
18
19
  #include <faiss/IndexFlat.h>
19
20
  #include <faiss/IndexHNSW.h>
20
21
  #include <faiss/IndexIVF.h>
@@ -27,11 +28,15 @@
27
28
  #include <faiss/IndexNSG.h>
28
29
  #include <faiss/IndexPQ.h>
29
30
  #include <faiss/IndexPreTransform.h>
30
- #include <faiss/IndexResidual.h>
31
31
  #include <faiss/IndexScalarQuantizer.h>
32
32
  #include <faiss/MetaIndexes.h>
33
33
  #include <faiss/VectorTransform.h>
34
34
 
35
+ #include <faiss/impl/LocalSearchQuantizer.h>
36
+ #include <faiss/impl/ProductQuantizer.h>
37
+ #include <faiss/impl/ResidualQuantizer.h>
38
+ #include <faiss/impl/ScalarQuantizer.h>
39
+
35
40
  namespace faiss {
36
41
 
37
42
  /*************************************************************
@@ -80,9 +85,10 @@ Index* Cloner::clone_Index(const Index* index) {
80
85
  TRYCLONE(IndexFlatIP, index)
81
86
  TRYCLONE(IndexFlat, index)
82
87
  TRYCLONE(IndexLattice, index)
83
- TRYCLONE(IndexResidual, index)
88
+ TRYCLONE(IndexResidualQuantizer, index)
84
89
  TRYCLONE(IndexScalarQuantizer, index)
85
90
  TRYCLONE(MultiIndexQuantizer, index)
91
+ TRYCLONE(ResidualCoarseQuantizer, index)
86
92
  if (const IndexIVF* ivf = dynamic_cast<const IndexIVF*>(index)) {
87
93
  IndexIVF* res = clone_IndexIVF(ivf);
88
94
  if (ivf->invlists == nullptr) {
@@ -116,7 +122,9 @@ Index* Cloner::clone_Index(const Index* index) {
116
122
  return res;
117
123
  } else if (
118
124
  const IndexIDMap* idmap = dynamic_cast<const IndexIDMap*>(index)) {
119
- IndexIDMap* res = new IndexIDMap(*idmap);
125
+ const IndexIDMap2* idmap2 = dynamic_cast<const IndexIDMap2*>(index);
126
+ IndexIDMap* res =
127
+ idmap2 ? new IndexIDMap2(*idmap2) : new IndexIDMap(*idmap);
120
128
  res->own_fields = true;
121
129
  res->index = clone_Index(idmap->index);
122
130
  return res;
@@ -136,6 +144,13 @@ Index* Cloner::clone_Index(const Index* index) {
136
144
  res->own_fields = true;
137
145
  res->storage = clone_Index(insg->storage);
138
146
  return res;
147
+ } else if (
148
+ const IndexNNDescent* innd =
149
+ dynamic_cast<const IndexNNDescent*>(index)) {
150
+ IndexNNDescent* res = new IndexNNDescent(*innd);
151
+ res->own_fields = true;
152
+ res->storage = clone_Index(innd->storage);
153
+ return res;
139
154
  } else if (
140
155
  const Index2Layer* i2l = dynamic_cast<const Index2Layer*>(index)) {
141
156
  Index2Layer* res = new Index2Layer(*i2l);
@@ -148,4 +163,12 @@ Index* Cloner::clone_Index(const Index* index) {
148
163
  return nullptr;
149
164
  }
150
165
 
166
+ Quantizer* clone_Quantizer(const Quantizer* quant) {
167
+ TRYCLONE(ResidualQuantizer, quant)
168
+ TRYCLONE(LocalSearchQuantizer, quant)
169
+ TRYCLONE(ProductQuantizer, quant)
170
+ TRYCLONE(ScalarQuantizer, quant)
171
+ FAISS_THROW_MSG("Did not recognize quantizer to clone");
172
+ }
173
+
151
174
  } // namespace faiss
@@ -16,6 +16,7 @@ namespace faiss {
16
16
  struct Index;
17
17
  struct IndexIVF;
18
18
  struct VectorTransform;
19
+ struct Quantizer;
19
20
 
20
21
  /* cloning functions */
21
22
  Index* clone_index(const Index*);
@@ -30,4 +31,6 @@ struct Cloner {
30
31
  virtual ~Cloner() {}
31
32
  };
32
33
 
34
+ Quantizer* clone_Quantizer(const Quantizer* quant);
35
+
33
36
  } // namespace faiss