faiss 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/ext/faiss/extconf.rb +1 -1
  4. data/lib/faiss/version.rb +1 -1
  5. data/vendor/faiss/benchs/bench_6bit_codec.cpp +80 -0
  6. data/vendor/faiss/c_api/AutoTune_c.h +2 -0
  7. data/vendor/faiss/c_api/IndexShards_c.cpp +0 -6
  8. data/vendor/faiss/c_api/IndexShards_c.h +1 -4
  9. data/vendor/faiss/c_api/gpu/GpuAutoTune_c.cpp +4 -2
  10. data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.cpp +1 -1
  11. data/vendor/faiss/c_api/gpu/GpuIndex_c.cpp +1 -1
  12. data/vendor/faiss/c_api/gpu/GpuResources_c.cpp +1 -1
  13. data/vendor/faiss/c_api/gpu/StandardGpuResources_c.cpp +1 -1
  14. data/vendor/faiss/demos/demo_imi_flat.cpp +5 -2
  15. data/vendor/faiss/demos/demo_imi_pq.cpp +6 -2
  16. data/vendor/faiss/demos/demo_ivfpq_indexing.cpp +7 -2
  17. data/vendor/faiss/{AutoTune.cpp → faiss/AutoTune.cpp} +9 -9
  18. data/vendor/faiss/{AutoTune.h → faiss/AutoTune.h} +0 -0
  19. data/vendor/faiss/{Clustering.cpp → faiss/Clustering.cpp} +13 -12
  20. data/vendor/faiss/{Clustering.h → faiss/Clustering.h} +0 -0
  21. data/vendor/faiss/{DirectMap.cpp → faiss/DirectMap.cpp} +0 -0
  22. data/vendor/faiss/{DirectMap.h → faiss/DirectMap.h} +0 -0
  23. data/vendor/faiss/{IVFlib.cpp → faiss/IVFlib.cpp} +86 -11
  24. data/vendor/faiss/{IVFlib.h → faiss/IVFlib.h} +26 -8
  25. data/vendor/faiss/{Index.cpp → faiss/Index.cpp} +0 -0
  26. data/vendor/faiss/{Index.h → faiss/Index.h} +1 -1
  27. data/vendor/faiss/{Index2Layer.cpp → faiss/Index2Layer.cpp} +12 -11
  28. data/vendor/faiss/{Index2Layer.h → faiss/Index2Layer.h} +0 -0
  29. data/vendor/faiss/{IndexBinary.cpp → faiss/IndexBinary.cpp} +2 -1
  30. data/vendor/faiss/{IndexBinary.h → faiss/IndexBinary.h} +0 -0
  31. data/vendor/faiss/{IndexBinaryFlat.cpp → faiss/IndexBinaryFlat.cpp} +0 -0
  32. data/vendor/faiss/{IndexBinaryFlat.h → faiss/IndexBinaryFlat.h} +0 -0
  33. data/vendor/faiss/{IndexBinaryFromFloat.cpp → faiss/IndexBinaryFromFloat.cpp} +1 -0
  34. data/vendor/faiss/{IndexBinaryFromFloat.h → faiss/IndexBinaryFromFloat.h} +0 -0
  35. data/vendor/faiss/{IndexBinaryHNSW.cpp → faiss/IndexBinaryHNSW.cpp} +1 -2
  36. data/vendor/faiss/{IndexBinaryHNSW.h → faiss/IndexBinaryHNSW.h} +0 -0
  37. data/vendor/faiss/{IndexBinaryHash.cpp → faiss/IndexBinaryHash.cpp} +16 -7
  38. data/vendor/faiss/{IndexBinaryHash.h → faiss/IndexBinaryHash.h} +2 -1
  39. data/vendor/faiss/{IndexBinaryIVF.cpp → faiss/IndexBinaryIVF.cpp} +10 -16
  40. data/vendor/faiss/{IndexBinaryIVF.h → faiss/IndexBinaryIVF.h} +1 -1
  41. data/vendor/faiss/{IndexFlat.cpp → faiss/IndexFlat.cpp} +0 -0
  42. data/vendor/faiss/{IndexFlat.h → faiss/IndexFlat.h} +0 -0
  43. data/vendor/faiss/{IndexHNSW.cpp → faiss/IndexHNSW.cpp} +63 -32
  44. data/vendor/faiss/{IndexHNSW.h → faiss/IndexHNSW.h} +0 -0
  45. data/vendor/faiss/{IndexIVF.cpp → faiss/IndexIVF.cpp} +129 -46
  46. data/vendor/faiss/{IndexIVF.h → faiss/IndexIVF.h} +7 -3
  47. data/vendor/faiss/{IndexIVFFlat.cpp → faiss/IndexIVFFlat.cpp} +6 -5
  48. data/vendor/faiss/{IndexIVFFlat.h → faiss/IndexIVFFlat.h} +0 -0
  49. data/vendor/faiss/{IndexIVFPQ.cpp → faiss/IndexIVFPQ.cpp} +9 -8
  50. data/vendor/faiss/{IndexIVFPQ.h → faiss/IndexIVFPQ.h} +4 -2
  51. data/vendor/faiss/{IndexIVFPQR.cpp → faiss/IndexIVFPQR.cpp} +3 -1
  52. data/vendor/faiss/{IndexIVFPQR.h → faiss/IndexIVFPQR.h} +0 -0
  53. data/vendor/faiss/{IndexIVFSpectralHash.cpp → faiss/IndexIVFSpectralHash.cpp} +1 -1
  54. data/vendor/faiss/{IndexIVFSpectralHash.h → faiss/IndexIVFSpectralHash.h} +0 -0
  55. data/vendor/faiss/{IndexLSH.cpp → faiss/IndexLSH.cpp} +0 -0
  56. data/vendor/faiss/{IndexLSH.h → faiss/IndexLSH.h} +0 -0
  57. data/vendor/faiss/{IndexLattice.cpp → faiss/IndexLattice.cpp} +0 -0
  58. data/vendor/faiss/{IndexLattice.h → faiss/IndexLattice.h} +0 -0
  59. data/vendor/faiss/{IndexPQ.cpp → faiss/IndexPQ.cpp} +6 -6
  60. data/vendor/faiss/{IndexPQ.h → faiss/IndexPQ.h} +3 -1
  61. data/vendor/faiss/{IndexPreTransform.cpp → faiss/IndexPreTransform.cpp} +0 -0
  62. data/vendor/faiss/{IndexPreTransform.h → faiss/IndexPreTransform.h} +0 -0
  63. data/vendor/faiss/{IndexReplicas.cpp → faiss/IndexReplicas.cpp} +102 -10
  64. data/vendor/faiss/{IndexReplicas.h → faiss/IndexReplicas.h} +6 -0
  65. data/vendor/faiss/{IndexScalarQuantizer.cpp → faiss/IndexScalarQuantizer.cpp} +3 -3
  66. data/vendor/faiss/{IndexScalarQuantizer.h → faiss/IndexScalarQuantizer.h} +0 -0
  67. data/vendor/faiss/{IndexShards.cpp → faiss/IndexShards.cpp} +37 -12
  68. data/vendor/faiss/{IndexShards.h → faiss/IndexShards.h} +3 -4
  69. data/vendor/faiss/{InvertedLists.cpp → faiss/InvertedLists.cpp} +2 -2
  70. data/vendor/faiss/{InvertedLists.h → faiss/InvertedLists.h} +1 -0
  71. data/vendor/faiss/{MatrixStats.cpp → faiss/MatrixStats.cpp} +0 -0
  72. data/vendor/faiss/{MatrixStats.h → faiss/MatrixStats.h} +0 -0
  73. data/vendor/faiss/{MetaIndexes.cpp → faiss/MetaIndexes.cpp} +5 -3
  74. data/vendor/faiss/{MetaIndexes.h → faiss/MetaIndexes.h} +0 -0
  75. data/vendor/faiss/{MetricType.h → faiss/MetricType.h} +0 -0
  76. data/vendor/faiss/{OnDiskInvertedLists.cpp → faiss/OnDiskInvertedLists.cpp} +141 -3
  77. data/vendor/faiss/{OnDiskInvertedLists.h → faiss/OnDiskInvertedLists.h} +27 -7
  78. data/vendor/faiss/{VectorTransform.cpp → faiss/VectorTransform.cpp} +4 -3
  79. data/vendor/faiss/{VectorTransform.h → faiss/VectorTransform.h} +0 -0
  80. data/vendor/faiss/{clone_index.cpp → faiss/clone_index.cpp} +0 -0
  81. data/vendor/faiss/{clone_index.h → faiss/clone_index.h} +0 -0
  82. data/vendor/faiss/{gpu → faiss/gpu}/GpuAutoTune.cpp +0 -0
  83. data/vendor/faiss/{gpu → faiss/gpu}/GpuAutoTune.h +0 -0
  84. data/vendor/faiss/{gpu → faiss/gpu}/GpuCloner.cpp +14 -14
  85. data/vendor/faiss/{gpu → faiss/gpu}/GpuCloner.h +6 -7
  86. data/vendor/faiss/{gpu → faiss/gpu}/GpuClonerOptions.cpp +0 -0
  87. data/vendor/faiss/{gpu → faiss/gpu}/GpuClonerOptions.h +0 -0
  88. data/vendor/faiss/{gpu → faiss/gpu}/GpuDistance.h +12 -4
  89. data/vendor/faiss/{gpu → faiss/gpu}/GpuFaissAssert.h +0 -0
  90. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndex.h +3 -9
  91. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexBinaryFlat.h +7 -7
  92. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexFlat.h +35 -10
  93. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVF.h +1 -2
  94. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFFlat.h +4 -3
  95. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFPQ.h +21 -4
  96. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFScalarQuantizer.h +4 -3
  97. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndicesOptions.h +0 -0
  98. data/vendor/faiss/faiss/gpu/GpuResources.cpp +200 -0
  99. data/vendor/faiss/faiss/gpu/GpuResources.h +264 -0
  100. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +572 -0
  101. data/vendor/faiss/{gpu → faiss/gpu}/StandardGpuResources.h +83 -15
  102. data/vendor/faiss/{gpu → faiss/gpu}/impl/RemapIndices.cpp +0 -0
  103. data/vendor/faiss/{gpu → faiss/gpu}/impl/RemapIndices.h +0 -0
  104. data/vendor/faiss/{gpu → faiss/gpu}/perf/IndexWrapper-inl.h +1 -1
  105. data/vendor/faiss/{gpu → faiss/gpu}/perf/IndexWrapper.h +1 -1
  106. data/vendor/faiss/{gpu → faiss/gpu}/perf/PerfClustering.cpp +1 -1
  107. data/vendor/faiss/{gpu → faiss/gpu}/perf/PerfIVFPQAdd.cpp +0 -0
  108. data/vendor/faiss/{gpu → faiss/gpu}/perf/WriteIndex.cpp +0 -0
  109. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexBinaryFlat.cpp +0 -0
  110. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexFlat.cpp +1 -1
  111. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexIVFFlat.cpp +0 -0
  112. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexIVFPQ.cpp +141 -52
  113. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuMemoryException.cpp +0 -0
  114. data/vendor/faiss/{gpu → faiss/gpu}/test/TestUtils.cpp +4 -2
  115. data/vendor/faiss/{gpu → faiss/gpu}/test/TestUtils.h +0 -0
  116. data/vendor/faiss/{gpu → faiss/gpu}/test/demo_ivfpq_indexing_gpu.cpp +7 -5
  117. data/vendor/faiss/{gpu → faiss/gpu}/utils/DeviceUtils.h +1 -1
  118. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +213 -0
  119. data/vendor/faiss/{gpu → faiss/gpu}/utils/StackDeviceMemory.h +25 -40
  120. data/vendor/faiss/{gpu → faiss/gpu}/utils/StaticUtils.h +0 -0
  121. data/vendor/faiss/{gpu → faiss/gpu}/utils/Timer.cpp +0 -0
  122. data/vendor/faiss/{gpu → faiss/gpu}/utils/Timer.h +0 -0
  123. data/vendor/faiss/{impl → faiss/impl}/AuxIndexStructures.cpp +1 -0
  124. data/vendor/faiss/{impl → faiss/impl}/AuxIndexStructures.h +3 -1
  125. data/vendor/faiss/{impl → faiss/impl}/FaissAssert.h +1 -0
  126. data/vendor/faiss/{impl → faiss/impl}/FaissException.cpp +26 -0
  127. data/vendor/faiss/{impl → faiss/impl}/FaissException.h +4 -0
  128. data/vendor/faiss/{impl → faiss/impl}/HNSW.cpp +26 -26
  129. data/vendor/faiss/{impl → faiss/impl}/HNSW.h +19 -11
  130. data/vendor/faiss/{impl → faiss/impl}/PolysemousTraining.cpp +1 -1
  131. data/vendor/faiss/{impl → faiss/impl}/PolysemousTraining.h +1 -1
  132. data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer-inl.h +0 -1
  133. data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer.cpp +9 -9
  134. data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer.h +0 -0
  135. data/vendor/faiss/{impl → faiss/impl}/ScalarQuantizer.cpp +63 -39
  136. data/vendor/faiss/{impl → faiss/impl}/ScalarQuantizer.h +1 -1
  137. data/vendor/faiss/{impl → faiss/impl}/ThreadedIndex-inl.h +0 -0
  138. data/vendor/faiss/{impl → faiss/impl}/ThreadedIndex.h +0 -0
  139. data/vendor/faiss/{impl → faiss/impl}/index_read.cpp +99 -116
  140. data/vendor/faiss/{impl → faiss/impl}/index_write.cpp +15 -50
  141. data/vendor/faiss/{impl → faiss/impl}/io.cpp +15 -10
  142. data/vendor/faiss/{impl → faiss/impl}/io.h +22 -8
  143. data/vendor/faiss/faiss/impl/io_macros.h +57 -0
  144. data/vendor/faiss/{impl → faiss/impl}/lattice_Zn.cpp +52 -36
  145. data/vendor/faiss/{impl → faiss/impl}/lattice_Zn.h +3 -3
  146. data/vendor/faiss/faiss/impl/platform_macros.h +24 -0
  147. data/vendor/faiss/{index_factory.cpp → faiss/index_factory.cpp} +33 -12
  148. data/vendor/faiss/{index_factory.h → faiss/index_factory.h} +0 -0
  149. data/vendor/faiss/{index_io.h → faiss/index_io.h} +55 -1
  150. data/vendor/faiss/faiss/python/python_callbacks.cpp +112 -0
  151. data/vendor/faiss/faiss/python/python_callbacks.h +45 -0
  152. data/vendor/faiss/{utils → faiss/utils}/Heap.cpp +5 -5
  153. data/vendor/faiss/{utils → faiss/utils}/Heap.h +1 -3
  154. data/vendor/faiss/{utils → faiss/utils}/WorkerThread.cpp +0 -0
  155. data/vendor/faiss/{utils → faiss/utils}/WorkerThread.h +0 -0
  156. data/vendor/faiss/{utils → faiss/utils}/distances.cpp +28 -13
  157. data/vendor/faiss/{utils → faiss/utils}/distances.h +2 -1
  158. data/vendor/faiss/{utils → faiss/utils}/distances_simd.cpp +5 -5
  159. data/vendor/faiss/{utils → faiss/utils}/extra_distances.cpp +8 -7
  160. data/vendor/faiss/{utils → faiss/utils}/extra_distances.h +0 -0
  161. data/vendor/faiss/{utils → faiss/utils}/hamming-inl.h +1 -3
  162. data/vendor/faiss/{utils → faiss/utils}/hamming.cpp +8 -7
  163. data/vendor/faiss/{utils → faiss/utils}/hamming.h +7 -1
  164. data/vendor/faiss/{utils → faiss/utils}/random.cpp +5 -5
  165. data/vendor/faiss/{utils → faiss/utils}/random.h +0 -0
  166. data/vendor/faiss/{utils → faiss/utils}/utils.cpp +27 -28
  167. data/vendor/faiss/{utils → faiss/utils}/utils.h +4 -0
  168. data/vendor/faiss/misc/test_blas.cpp +4 -1
  169. data/vendor/faiss/tests/test_binary_flat.cpp +0 -2
  170. data/vendor/faiss/tests/test_dealloc_invlists.cpp +6 -1
  171. data/vendor/faiss/tests/test_ivfpq_codec.cpp +4 -1
  172. data/vendor/faiss/tests/test_ivfpq_indexing.cpp +6 -4
  173. data/vendor/faiss/tests/test_lowlevel_ivf.cpp +12 -5
  174. data/vendor/faiss/tests/test_merge.cpp +6 -3
  175. data/vendor/faiss/tests/test_ondisk_ivf.cpp +7 -2
  176. data/vendor/faiss/tests/test_pairs_decoding.cpp +5 -1
  177. data/vendor/faiss/tests/test_params_override.cpp +7 -2
  178. data/vendor/faiss/tests/test_sliding_ivf.cpp +10 -4
  179. data/vendor/faiss/tutorial/cpp/1-Flat.cpp +14 -8
  180. data/vendor/faiss/tutorial/cpp/2-IVFFlat.cpp +11 -7
  181. data/vendor/faiss/tutorial/cpp/3-IVFPQ.cpp +12 -7
  182. data/vendor/faiss/tutorial/cpp/4-GPU.cpp +6 -3
  183. data/vendor/faiss/tutorial/cpp/5-Multiple-GPUs.cpp +7 -3
  184. metadata +154 -153
  185. data/vendor/faiss/gpu/GpuResources.cpp +0 -52
  186. data/vendor/faiss/gpu/GpuResources.h +0 -73
  187. data/vendor/faiss/gpu/StandardGpuResources.cpp +0 -303
  188. data/vendor/faiss/gpu/utils/DeviceMemory.cpp +0 -77
  189. data/vendor/faiss/gpu/utils/DeviceMemory.h +0 -71
  190. data/vendor/faiss/gpu/utils/MemorySpace.cpp +0 -89
  191. data/vendor/faiss/gpu/utils/MemorySpace.h +0 -44
  192. data/vendor/faiss/gpu/utils/StackDeviceMemory.cpp +0 -239
@@ -65,9 +65,15 @@ class IndexReplicasTemplate : public ThreadedIndex<IndexT> {
65
65
  /// reconstructs from the first index
66
66
  void reconstruct(idx_t, component_t *v) const override;
67
67
 
68
+ /// Synchronize the top-level index (IndexShards) with data in the sub-indices
69
+ void syncWithSubIndexes();
70
+
68
71
  protected:
69
72
  /// Called just after an index is added
70
73
  void onAfterAddIndex(IndexT* index) override;
74
+
75
+ /// Called just after an index is removed
76
+ void onAfterRemoveIndex(IndexT* index) override;
71
77
  };
72
78
 
73
79
  using IndexReplicas = IndexReplicasTemplate<Index>;
@@ -77,7 +77,7 @@ void IndexScalarQuantizer::search(
77
77
  ScopeDeleter1<InvertedListScanner> del(scanner);
78
78
 
79
79
  #pragma omp for
80
- for (size_t i = 0; i < n; i++) {
80
+ for (idx_t i = 0; i < n; i++) {
81
81
  float * D = distances + k * i;
82
82
  idx_t * I = labels + k * i;
83
83
  // re-order heap
@@ -197,7 +197,7 @@ void IndexIVFScalarQuantizer::encode_vectors(idx_t n, const float* x,
197
197
  std::vector<float> residual (d);
198
198
 
199
199
  #pragma omp for
200
- for (size_t i = 0; i < n; i++) {
200
+ for (idx_t i = 0; i < n; i++) {
201
201
  int64_t list_no = list_nos [i];
202
202
  if (list_no >= 0) {
203
203
  const float *xi = x + i * d;
@@ -227,7 +227,7 @@ void IndexIVFScalarQuantizer::sa_decode (idx_t n, const uint8_t *codes,
227
227
  std::vector<float> residual (d);
228
228
 
229
229
  #pragma omp for
230
- for (size_t i = 0; i < n; i++) {
230
+ for (idx_t i = 0; i < n; i++) {
231
231
  const uint8_t *code = codes + i * (code_size + coarse_size);
232
232
  int64_t list_no = decode_listno (code);
233
233
  float *xi = x + i * d;
@@ -9,6 +9,7 @@
9
9
 
10
10
  #include <faiss/IndexShards.h>
11
11
 
12
+ #include <cinttypes>
12
13
  #include <cstdio>
13
14
  #include <functional>
14
15
 
@@ -132,18 +133,20 @@ IndexShardsTemplate<IndexT>::IndexShardsTemplate(bool threaded,
132
133
  template <typename IndexT>
133
134
  void
134
135
  IndexShardsTemplate<IndexT>::onAfterAddIndex(IndexT* index /* unused */) {
135
- sync_with_shard_indexes();
136
+ syncWithSubIndexes();
136
137
  }
137
138
 
138
139
  template <typename IndexT>
139
140
  void
140
141
  IndexShardsTemplate<IndexT>::onAfterRemoveIndex(IndexT* index /* unused */) {
141
- sync_with_shard_indexes();
142
+ syncWithSubIndexes();
142
143
  }
143
144
 
145
+ // FIXME: assumes that nothing is currently running on the sub-indexes, which is
146
+ // true with the normal API, but should use the runOnIndex API instead
144
147
  template <typename IndexT>
145
148
  void
146
- IndexShardsTemplate<IndexT>::sync_with_shard_indexes() {
149
+ IndexShardsTemplate<IndexT>::syncWithSubIndexes() {
147
150
  if (!this->count()) {
148
151
  this->is_trained = false;
149
152
  this->ntotal = 0;
@@ -160,6 +163,31 @@ IndexShardsTemplate<IndexT>::sync_with_shard_indexes() {
160
163
  auto index = this->at(i);
161
164
  FAISS_THROW_IF_NOT(this->metric_type == index->metric_type);
162
165
  FAISS_THROW_IF_NOT(this->d == index->d);
166
+ FAISS_THROW_IF_NOT(this->is_trained == index->is_trained);
167
+
168
+ this->ntotal += index->ntotal;
169
+ }
170
+ }
171
+
172
+ // No metric_type for IndexBinary
173
+ template <>
174
+ void
175
+ IndexShardsTemplate<IndexBinary>::syncWithSubIndexes() {
176
+ if (!this->count()) {
177
+ this->is_trained = false;
178
+ this->ntotal = 0;
179
+
180
+ return;
181
+ }
182
+
183
+ auto firstIndex = this->at(0);
184
+ this->is_trained = firstIndex->is_trained;
185
+ this->ntotal = firstIndex->ntotal;
186
+
187
+ for (int i = 1; i < this->count(); ++i) {
188
+ auto index = this->at(i);
189
+ FAISS_THROW_IF_NOT(this->d == index->d);
190
+ FAISS_THROW_IF_NOT(this->is_trained == index->is_trained);
163
191
 
164
192
  this->ntotal += index->ntotal;
165
193
  }
@@ -172,7 +200,7 @@ IndexShardsTemplate<IndexT>::train(idx_t n,
172
200
  auto fn =
173
201
  [n, x](int no, IndexT *index) {
174
202
  if (index->verbose) {
175
- printf("begin train shard %d on %ld points\n", no, n);
203
+ printf("begin train shard %d on %" PRId64 " points\n", no, n);
176
204
  }
177
205
 
178
206
  index->train(n, x);
@@ -183,7 +211,7 @@ IndexShardsTemplate<IndexT>::train(idx_t n,
183
211
  };
184
212
 
185
213
  this->runOnIndex(fn);
186
- sync_with_shard_indexes();
214
+ syncWithSubIndexes();
187
215
  }
188
216
 
189
217
  template <typename IndexT>
@@ -237,7 +265,7 @@ IndexShardsTemplate<IndexT>::add_with_ids(idx_t n,
237
265
  auto x0 = x + i0 * components_per_vec;
238
266
 
239
267
  if (index->verbose) {
240
- printf ("begin add shard %d on %ld points\n", no, n);
268
+ printf ("begin add shard %d on %" PRId64 " points\n", no, n);
241
269
  }
242
270
 
243
271
  if (ids) {
@@ -247,15 +275,12 @@ IndexShardsTemplate<IndexT>::add_with_ids(idx_t n,
247
275
  }
248
276
 
249
277
  if (index->verbose) {
250
- printf ("end add shard %d on %ld points\n", no, i1 - i0);
278
+ printf ("end add shard %d on %" PRId64 " points\n", no, i1 - i0);
251
279
  }
252
280
  };
253
281
 
254
282
  this->runOnIndex(fn);
255
-
256
- // This is safe to do here because the current thread controls execution in
257
- // all threads, and nothing else is happening
258
- this->ntotal += n;
283
+ syncWithSubIndexes();
259
284
  }
260
285
 
261
286
  template <typename IndexT>
@@ -273,7 +298,7 @@ IndexShardsTemplate<IndexT>::search(idx_t n,
273
298
  auto fn =
274
299
  [n, k, x, &all_distances, &all_labels](int no, const IndexT *index) {
275
300
  if (index->verbose) {
276
- printf ("begin query shard %d on %ld points\n", no, n);
301
+ printf ("begin query shard %d on %" PRId64 " points\n", no, n);
277
302
  }
278
303
 
279
304
  index->search (n, x, k,
@@ -79,12 +79,11 @@ struct IndexShardsTemplate : public ThreadedIndex<IndexT> {
79
79
 
80
80
  void train(idx_t n, const component_t* x) override;
81
81
 
82
- // update metric_type and ntotal. Call if you changes something in
83
- // the shard indexes.
84
- void sync_with_shard_indexes();
85
-
86
82
  bool successive_ids;
87
83
 
84
+ /// Synchronize the top-level index (IndexShards) with data in the sub-indices
85
+ void syncWithSubIndexes();
86
+
88
87
  protected:
89
88
  /// Called just after an index is added
90
89
  void onAfterAddIndex(IndexT* index) override;
@@ -274,7 +274,7 @@ const uint8_t * HStackInvertedLists::get_single_code (
274
274
  }
275
275
  offset -= sz;
276
276
  }
277
- FAISS_THROW_FMT ("offset %ld unknown", offset);
277
+ FAISS_THROW_FMT ("offset %zd unknown", offset);
278
278
  }
279
279
 
280
280
 
@@ -309,7 +309,7 @@ Index::idx_t HStackInvertedLists::get_single_id (
309
309
  }
310
310
  offset -= sz;
311
311
  }
312
- FAISS_THROW_FMT ("offset %ld unknown", offset);
312
+ FAISS_THROW_FMT ("offset %zd unknown", offset);
313
313
  }
314
314
 
315
315
 
@@ -208,6 +208,7 @@ struct ArrayInvertedLists: InvertedLists {
208
208
  * that can be stacked horizontally, vertically and sliced.
209
209
  *****************************************************************/
210
210
 
211
+ /// invlists that fail for all write functions
211
212
  struct ReadOnlyInvertedLists: InvertedLists {
212
213
 
213
214
  ReadOnlyInvertedLists (size_t nlist, size_t code_size):
@@ -9,7 +9,9 @@
9
9
 
10
10
  #include <faiss/MetaIndexes.h>
11
11
 
12
+ #include <cinttypes>
12
13
  #include <cstdio>
14
+ #include <limits>
13
15
  #include <stdint.h>
14
16
 
15
17
  #include <faiss/impl/FaissAssert.h>
@@ -199,7 +201,7 @@ void IndexIDMap2Template<IndexT>::reconstruct
199
201
  try {
200
202
  this->index->reconstruct (rev_map.at (key), recons);
201
203
  } catch (const std::out_of_range& e) {
202
- FAISS_THROW_FMT ("key %ld not found", key);
204
+ FAISS_THROW_FMT ("key %" PRId64 " not found", key);
203
205
  }
204
206
  }
205
207
 
@@ -274,7 +276,7 @@ void IndexSplitVectors::search (
274
276
  float *distances1 = no == 0 ? distances : all_distances + no * k * n;
275
277
  idx_t *labels1 = no == 0 ? labels : all_labels + no * k * n;
276
278
  if (index->verbose)
277
- printf ("begin query shard %d on %ld points\n", no, n);
279
+ printf ("begin query shard %d on %" PRId64 " points\n", no, n);
278
280
  const Index * sub_index = index->sub_indexes[no];
279
281
  int64_t sub_d = sub_index->d, d = index->d;
280
282
  idx_t ofs = 0;
@@ -319,7 +321,7 @@ void IndexSplitVectors::search (
319
321
  distances[j] += distances_i[j];
320
322
  } else {
321
323
  labels[j] = -1;
322
- distances[j] = 0.0 / 0.0;
324
+ distances[j] = std::numeric_limits<float>::quiet_NaN();
323
325
  }
324
326
  }
325
327
  }
@@ -16,10 +16,14 @@
16
16
  #include <sys/mman.h>
17
17
  #include <unistd.h>
18
18
  #include <sys/types.h>
19
+ #include <sys/stat.h>
19
20
 
20
21
  #include <faiss/impl/FaissAssert.h>
21
22
  #include <faiss/utils/utils.h>
22
23
 
24
+ #include <faiss/impl/io.h>
25
+ #include <faiss/impl/io_macros.h>
26
+
23
27
 
24
28
  namespace faiss {
25
29
 
@@ -320,7 +324,7 @@ void OnDiskInvertedLists::update_totsize (size_t new_size)
320
324
  totsize = new_size;
321
325
 
322
326
  // create file
323
- printf ("resizing %s to %ld bytes\n", filename.c_str(), totsize);
327
+ printf ("resizing %s to %zd bytes\n", filename.c_str(), totsize);
324
328
 
325
329
  int err = truncate (filename.c_str(), totsize);
326
330
 
@@ -341,7 +345,7 @@ void OnDiskInvertedLists::update_totsize (size_t new_size)
341
345
 
342
346
  #define INVALID_OFFSET (size_t)(-1)
343
347
 
344
- OnDiskInvertedLists::List::List ():
348
+ OnDiskOneList::OnDiskOneList ():
345
349
  size (0), capacity (0), offset (INVALID_OFFSET)
346
350
  {}
347
351
 
@@ -640,7 +644,7 @@ size_t OnDiskInvertedLists::merge_from (const InvertedLists **ils, int n_il,
640
644
  nmerged++;
641
645
  double t1 = getmillisecs();
642
646
  if (t1 - last_t > 500) {
643
- printf("merged %ld lists in %.3f s\r",
647
+ printf("merged %zd lists in %.3f s\r",
644
648
  nmerged, (t1 - t0) / 1000.0);
645
649
  fflush(stdout);
646
650
  last_t = t1;
@@ -656,6 +660,12 @@ size_t OnDiskInvertedLists::merge_from (const InvertedLists **ils, int n_il,
656
660
  }
657
661
 
658
662
 
663
+ size_t OnDiskInvertedLists::merge_from_1 (const InvertedLists *ils, bool verbose)
664
+ {
665
+ return merge_from (&ils, 1, verbose);
666
+ }
667
+
668
+
659
669
  void OnDiskInvertedLists::crop_invlists(size_t l0, size_t l1)
660
670
  {
661
671
  FAISS_THROW_IF_NOT(0 <= l0 && l0 <= l1 && l1 <= nlist);
@@ -668,6 +678,134 @@ void OnDiskInvertedLists::crop_invlists(size_t l0, size_t l1)
668
678
  nlist = l1 - l0;
669
679
  }
670
680
 
681
+ /*******************************************************
682
+ * I/O support via callbacks
683
+ *******************************************************/
684
+
685
+
686
+
687
+
688
+ OnDiskInvertedListsIOHook::OnDiskInvertedListsIOHook():
689
+ InvertedListsIOHook("ilod", typeid(OnDiskInvertedLists).name())
690
+ {}
691
+
692
+
693
+ void OnDiskInvertedListsIOHook::write(const InvertedLists *ils, IOWriter *f) const
694
+ {
695
+ uint32_t h = fourcc ("ilod");
696
+ WRITE1 (h);
697
+ WRITE1 (ils->nlist);
698
+ WRITE1 (ils->code_size);
699
+ const OnDiskInvertedLists *od = dynamic_cast<const OnDiskInvertedLists*> (ils);
700
+ // this is a POD object
701
+ WRITEVECTOR (od->lists);
702
+
703
+ {
704
+ std::vector<OnDiskInvertedLists::Slot> v(
705
+ od->slots.begin(), od->slots.end());
706
+ WRITEVECTOR(v);
707
+ }
708
+ {
709
+ std::vector<char> x(od->filename.begin(), od->filename.end());
710
+ WRITEVECTOR(x);
711
+ }
712
+ WRITE1(od->totsize);
713
+ }
714
+
715
+ InvertedLists * OnDiskInvertedListsIOHook::read(IOReader *f, int io_flags) const
716
+ {
717
+ OnDiskInvertedLists *od = new OnDiskInvertedLists();
718
+ od->read_only = io_flags & IO_FLAG_READ_ONLY;
719
+ READ1 (od->nlist);
720
+ READ1 (od->code_size);
721
+ // this is a POD object
722
+ READVECTOR (od->lists);
723
+ {
724
+ std::vector<OnDiskInvertedLists::Slot> v;
725
+ READVECTOR(v);
726
+ od->slots.assign(v.begin(), v.end());
727
+ }
728
+ {
729
+ std::vector<char> x;
730
+ READVECTOR(x);
731
+ od->filename.assign(x.begin(), x.end());
732
+
733
+ if (io_flags & IO_FLAG_ONDISK_SAME_DIR) {
734
+ FileIOReader *reader = dynamic_cast<FileIOReader*>(f);
735
+ FAISS_THROW_IF_NOT_MSG (
736
+ reader, "IO_FLAG_ONDISK_SAME_DIR only supported "
737
+ "when reading from file");
738
+ std::string indexname = reader->name;
739
+ std::string dirname = "./";
740
+ size_t slash = indexname.find_last_of('/');
741
+ if (slash != std::string::npos) {
742
+ dirname = indexname.substr(0, slash + 1);
743
+ }
744
+ std::string filename = od->filename;
745
+ slash = filename.find_last_of('/');
746
+ if (slash != std::string::npos) {
747
+ filename = filename.substr(slash + 1);
748
+ }
749
+ filename = dirname + filename;
750
+ printf("IO_FLAG_ONDISK_SAME_DIR: "
751
+ "updating ondisk filename from %s to %s\n",
752
+ od->filename.c_str(), filename.c_str());
753
+ od->filename = filename;
754
+ }
755
+
756
+ }
757
+ READ1(od->totsize);
758
+ od->do_mmap();
759
+ return od;
760
+ }
761
+
762
+ /** read from a ArrayInvertedLists into this invertedlist type */
763
+ InvertedLists * OnDiskInvertedListsIOHook::read_ArrayInvertedLists(
764
+ IOReader *f, int /* io_flags */,
765
+ size_t nlist, size_t code_size,
766
+ const std::vector<size_t> &sizes) const
767
+ {
768
+ auto ails = new OnDiskInvertedLists ();
769
+ ails->nlist = nlist;
770
+ ails->code_size = code_size;
771
+ ails->read_only = true;
772
+ ails->lists.resize (nlist);
773
+
774
+ FileIOReader *reader = dynamic_cast<FileIOReader*>(f);
775
+ FAISS_THROW_IF_NOT_MSG(reader, "mmap only supported for File objects");
776
+ FILE *fdesc = reader->f;
777
+ size_t o0 = ftell(fdesc);
778
+ size_t o = o0;
779
+ { // do the mmap
780
+ struct stat buf;
781
+ int ret = fstat (fileno(fdesc), &buf);
782
+ FAISS_THROW_IF_NOT_FMT (ret == 0,
783
+ "fstat failed: %s", strerror(errno));
784
+ ails->totsize = buf.st_size;
785
+ ails->ptr = (uint8_t*)mmap (nullptr, ails->totsize,
786
+ PROT_READ, MAP_SHARED,
787
+ fileno(fdesc), 0);
788
+ FAISS_THROW_IF_NOT_FMT (ails->ptr != MAP_FAILED,
789
+ "could not mmap: %s",
790
+ strerror(errno));
791
+ }
792
+
793
+ FAISS_THROW_IF_NOT(o <= ails->totsize);
794
+
795
+ for (size_t i = 0; i < ails->nlist; i++) {
796
+ OnDiskInvertedLists::List & l = ails->lists[i];
797
+ l.size = l.capacity = sizes[i];
798
+ l.offset = o;
799
+ o += l.size * (sizeof(OnDiskInvertedLists::idx_t) +
800
+ ails->code_size);
801
+ }
802
+ // resume normal reading of file
803
+ fseek (fdesc, o, SEEK_SET);
804
+
805
+ return ails;
806
+ }
807
+
808
+
671
809
 
672
810
 
673
811
 
@@ -12,14 +12,26 @@
12
12
 
13
13
  #include <vector>
14
14
  #include <list>
15
+ #include <typeinfo>
15
16
 
16
17
  #include <faiss/IndexIVF.h>
17
18
 
19
+ #include <faiss/index_io.h>
20
+
18
21
  namespace faiss {
19
22
 
20
23
 
21
24
  struct LockLevels;
22
25
 
26
+
27
+ struct OnDiskOneList {
28
+ size_t size; // size of inverted list (entries)
29
+ size_t capacity; // allocated size (entries)
30
+ size_t offset; // offset in buffer (bytes)
31
+ OnDiskOneList ();
32
+ };
33
+
34
+
23
35
  /** On-disk storage of inverted lists.
24
36
  *
25
37
  * The data is stored in a mmapped chunk of memory (base ptointer ptr,
@@ -49,13 +61,7 @@ struct LockLevels;
49
61
  * lists in parallel.
50
62
  */
51
63
  struct OnDiskInvertedLists: InvertedLists {
52
-
53
- struct List {
54
- size_t size; // size of inverted list (entries)
55
- size_t capacity; // allocated size (entries)
56
- size_t offset; // offset in buffer (bytes)
57
- List ();
58
- };
64
+ using List = OnDiskOneList;
59
65
 
60
66
  // size nlist
61
67
  std::vector<List> lists;
@@ -95,6 +101,9 @@ struct OnDiskInvertedLists: InvertedLists {
95
101
  // allocating slots)
96
102
  size_t merge_from (const InvertedLists **ils, int n_il, bool verbose=false);
97
103
 
104
+ /// same as merge_from for a single invlist
105
+ size_t merge_from_1 (const InvertedLists *il, bool verbose=false);
106
+
98
107
  /// restrict the inverted lists to l0:l1 without touching the mmapped region
99
108
  void crop_invlists(size_t l0, size_t l1);
100
109
 
@@ -121,6 +130,17 @@ struct OnDiskInvertedLists: InvertedLists {
121
130
  OnDiskInvertedLists ();
122
131
  };
123
132
 
133
+ struct OnDiskInvertedListsIOHook: InvertedListsIOHook {
134
+ OnDiskInvertedListsIOHook();
135
+ void write(const InvertedLists *ils, IOWriter *f) const override;
136
+ InvertedLists * read(IOReader *f, int io_flags) const override;
137
+ InvertedLists * read_ArrayInvertedLists(
138
+ IOReader *f, int io_flags,
139
+ size_t nlist, size_t code_size,
140
+ const std::vector<size_t> &sizes) const override;
141
+ };
142
+
143
+
124
144
 
125
145
  } // namespace faiss
126
146