faiss 0.6.1 → 0.6.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +3 -1
- data/vendor/faiss/faiss/Clustering.cpp +9 -1
- data/vendor/faiss/faiss/IVFlib.cpp +14 -3
- data/vendor/faiss/faiss/Index.h +2 -2
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +9 -10
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +2 -3
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +1 -2
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +10 -12
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +5 -9
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +5 -7
- data/vendor/faiss/faiss/IndexEDEN.cpp +273 -0
- data/vendor/faiss/faiss/IndexEDEN.h +57 -0
- data/vendor/faiss/faiss/IndexFastScan.cpp +15 -4
- data/vendor/faiss/faiss/IndexFlat.cpp +13 -50
- data/vendor/faiss/faiss/IndexHNSW.cpp +177 -148
- data/vendor/faiss/faiss/IndexIDMap.cpp +16 -3
- data/vendor/faiss/faiss/IndexIDMap.h +2 -0
- data/vendor/faiss/faiss/IndexIVF.cpp +19 -8
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +3 -4
- data/vendor/faiss/faiss/IndexIVFEDEN.cpp +302 -0
- data/vendor/faiss/faiss/IndexIVFEDEN.h +70 -0
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +5 -6
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +6 -5
- data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +3 -3
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +42 -25
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +0 -1
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -3
- data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +23 -62
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +180 -76
- data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +5 -4
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +8 -6
- data/vendor/faiss/faiss/IndexLSH.cpp +2 -3
- data/vendor/faiss/faiss/IndexLattice.cpp +5 -0
- data/vendor/faiss/faiss/IndexNNDescent.cpp +10 -3
- data/vendor/faiss/faiss/IndexNSG.cpp +8 -4
- data/vendor/faiss/faiss/IndexPQ.cpp +6 -8
- data/vendor/faiss/faiss/IndexPreTransform.cpp +15 -0
- data/vendor/faiss/faiss/IndexRaBitQ.cpp +2 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +1 -2
- data/vendor/faiss/faiss/IndexRaBitQFastScan.h +5 -1
- data/vendor/faiss/faiss/IndexRefine.cpp +30 -1
- data/vendor/faiss/faiss/IndexReplicas.cpp +1 -2
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +68 -6
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +10 -0
- data/vendor/faiss/faiss/IndexShards.cpp +2 -2
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +2 -2
- data/vendor/faiss/faiss/MetaIndexes.cpp +2 -4
- data/vendor/faiss/faiss/SuperKMeans.cpp +256 -240
- data/vendor/faiss/faiss/SuperKMeans.h +30 -0
- data/vendor/faiss/faiss/VectorTransform.cpp +33 -2
- data/vendor/faiss/faiss/clone_index.cpp +5 -0
- data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +1 -1
- data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +902 -12
- data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +702 -10
- data/vendor/faiss/faiss/factory_tools.cpp +51 -4
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +11 -11
- data/vendor/faiss/faiss/gpu/GpuIndex.h +34 -11
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +47 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +17 -0
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +16 -0
- data/vendor/faiss/faiss/gpu/GpuResources.h +3 -2
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +11 -12
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +3 -3
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +1 -1
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +2 -2
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +180 -0
- data/vendor/faiss/faiss/gpu_metal/MetalDistance.h +87 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndex.h +7 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFFlat.h +177 -0
- data/vendor/faiss/faiss/gpu_metal/MetalIndexIVFPQ.h +88 -0
- data/vendor/faiss/faiss/gpu_metal/MetalKernels.h +48 -3
- data/vendor/faiss/faiss/gpu_metal/MetalPythonBridge.h +45 -0
- data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFFlat.h +193 -0
- data/vendor/faiss/faiss/gpu_metal/impl/MetalIVFPQ.h +134 -0
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +2 -2
- data/vendor/faiss/faiss/impl/DistanceComputer.h +34 -0
- data/vendor/faiss/faiss/impl/EDENQuantizer.h +119 -0
- data/vendor/faiss/faiss/impl/HNSW.cpp +658 -344
- data/vendor/faiss/faiss/impl/HNSW.h +51 -13
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +2 -2
- data/vendor/faiss/faiss/impl/NSG.cpp +18 -12
- data/vendor/faiss/faiss/impl/Panorama.h +20 -7
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +152 -84
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +59 -24
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +45 -37
- data/vendor/faiss/faiss/impl/RaBitQUtils.h +35 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +175 -68
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +19 -0
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +2 -11
- data/vendor/faiss/faiss/impl/ResultHandler.h +26 -31
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +522 -58
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +70 -0
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +2 -2
- data/vendor/faiss/faiss/impl/VisitedTable.cpp +33 -13
- data/vendor/faiss/faiss/impl/VisitedTable.h +88 -33
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +1 -1
- data/vendor/faiss/faiss/impl/binary_hamming/avx2.cpp +4 -4
- data/vendor/faiss/faiss/impl/fast_scan/dispatching.h +38 -3
- data/vendor/faiss/faiss/impl/hnsw/LockVector.cpp +1 -1
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.cpp +35 -43
- data/vendor/faiss/faiss/impl/hnsw/MinimaxHeap.h +64 -15
- data/vendor/faiss/faiss/impl/hnsw/avx2.cpp +86 -40
- data/vendor/faiss/faiss/impl/hnsw/avx512.cpp +81 -50
- data/vendor/faiss/faiss/impl/index_read.cpp +476 -75
- data/vendor/faiss/faiss/impl/index_write.cpp +56 -4
- data/vendor/faiss/faiss/impl/io_macros.h +25 -0
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +8 -9
- data/vendor/faiss/faiss/impl/platform_macros.h +15 -9
- data/vendor/faiss/faiss/impl/polysemous_training/avx512.cpp +284 -0
- data/vendor/faiss/faiss/impl/polysemous_training/dispatch.h +115 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQ_QueryTables.cpp +0 -1
- data/vendor/faiss/faiss/impl/pq_code_distance/PQDistanceComputer_impl.h +26 -15
- data/vendor/faiss/faiss/impl/pq_code_distance/avx2.cpp +6 -4
- data/vendor/faiss/faiss/impl/pq_code_distance/avx512.cpp +2 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/neon.cpp +2 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +20 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-inl.h +36 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-sve.cpp +5 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_scan_impl.h +105 -0
- data/vendor/faiss/faiss/impl/pq_code_distance/rvv.cpp +2 -0
- data/vendor/faiss/faiss/impl/result_handler/ResultHandler.cpp +195 -0
- data/vendor/faiss/faiss/impl/result_handler/avx2.cpp +133 -0
- data/vendor/faiss/faiss/impl/result_handler/avx512.cpp +281 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx2.cpp +72 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer-avx512.cpp +228 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer.cpp +882 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +6 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/quantizers.h +336 -26
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +331 -32
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-impl.h +553 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512-spr.cpp +558 -0
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx512.cpp +284 -45
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +502 -3
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +157 -32
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-rvv.cpp +26 -0
- data/vendor/faiss/faiss/impl/simd_dispatch.h +86 -8
- data/vendor/faiss/faiss/index_factory.cpp +37 -7
- data/vendor/faiss/faiss/index_io.h +16 -0
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +5 -2
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +15 -15
- data/vendor/faiss/faiss/invlists/InvertedLists.h +2 -2
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +19 -4
- data/vendor/faiss/faiss/python/python_callbacks.cpp +3 -1
- data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +60 -0
- data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +26 -1
- data/vendor/faiss/faiss/svs/IndexSVSFlat.h +13 -0
- data/vendor/faiss/faiss/svs/IndexSVSIVF.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSIVFLeanVec.cpp +1 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +150 -23
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +30 -7
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +3 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +65 -25
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +3 -2
- data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +1 -1
- data/vendor/faiss/faiss/utils/bf16.h +34 -0
- data/vendor/faiss/faiss/utils/distances.cpp +14 -2
- data/vendor/faiss/faiss/utils/distances_simd.cpp +4 -4
- data/vendor/faiss/faiss/utils/extra_distances.cpp +4 -14
- data/vendor/faiss/faiss/utils/extra_distances.h +1 -2
- data/vendor/faiss/faiss/utils/hamming.cpp +9 -9
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx2.cpp +2 -1
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +15 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +6 -30
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512_spr.h +171 -0
- data/vendor/faiss/faiss/utils/partitioning.cpp +0 -2
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +29 -8
- data/vendor/faiss/faiss/utils/rabitq_simd.h +202 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx2.cpp +0 -1
- data/vendor/faiss/faiss/utils/simd_impl/distances_avx512.cpp +263 -15
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +160 -18
- data/vendor/faiss/faiss/utils/simd_impl/partitioning_simdlib256.h +14 -68
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx2.cpp +245 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +273 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512_spr.cpp +435 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_neon.cpp +11 -0
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_rvv.cpp +143 -6
- data/vendor/faiss/faiss/utils/simd_levels.cpp +56 -2
- data/vendor/faiss/faiss/utils/simd_levels.h +14 -0
- data/vendor/faiss/faiss/utils/utils.cpp +9 -27
- metadata +27 -2
|
@@ -229,60 +229,30 @@ struct RaBitInvertedListScanner : InvertedListScanner {
|
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
// Multi-bit: Two-stage search with adaptive filtering
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
float est_distance = rabitq_dc->distance_to_code_1bit(codes);
|
|
244
|
-
|
|
245
|
-
size_t code_size_base = (ivf_rabitq.d + 7) / 8;
|
|
246
|
-
const rabitq_utils::SignBitFactorsWithError* base_fac =
|
|
247
|
-
reinterpret_cast<
|
|
248
|
-
const rabitq_utils::SignBitFactorsWithError*>(
|
|
249
|
-
codes + code_size_base);
|
|
250
|
-
|
|
251
|
-
bool should_refine = rabitq_utils::should_refine_candidate(
|
|
252
|
-
est_distance,
|
|
253
|
-
base_fac->f_error,
|
|
254
|
-
rabitq_dc->g_error,
|
|
255
|
-
handler.threshold,
|
|
256
|
-
keep_max);
|
|
257
|
-
if (should_refine) {
|
|
258
|
-
// Refining computes the full distance — counts as a
|
|
259
|
-
// post-filter "distance computed" for stats purposes.
|
|
260
|
-
handler.stats.scan_cnt++;
|
|
261
|
-
float dis = distance_to_code(codes);
|
|
262
|
-
int64_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
263
|
-
|
|
264
|
-
if (handler.add_result(dis, id)) {
|
|
265
|
-
handler.stats.nheap_updates++;
|
|
266
|
-
nup++;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
codes += code_size;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return nup;
|
|
232
|
+
return rabitq_dc->scan_codes_multibit(
|
|
233
|
+
list_size,
|
|
234
|
+
codes,
|
|
235
|
+
ids,
|
|
236
|
+
code_size,
|
|
237
|
+
list_no,
|
|
238
|
+
store_pairs,
|
|
239
|
+
sel,
|
|
240
|
+
keep_max,
|
|
241
|
+
handler);
|
|
273
242
|
}
|
|
274
243
|
|
|
275
244
|
void internal_try_setup_dc() {
|
|
276
245
|
if (!query_vector.empty() && !reconstructed_centroid.empty()) {
|
|
277
|
-
// both query_vector and centroid are available
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
246
|
+
// both query_vector and centroid are available
|
|
247
|
+
if (!dc) {
|
|
248
|
+
dc.reset(ivf_rabitq.rabitq.get_distance_computer(
|
|
249
|
+
qb, nullptr, centered));
|
|
250
|
+
// Try to cast to RaBitQDistanceComputer for multi-bit support
|
|
251
|
+
rabitq_dc = dynamic_cast<RaBitQDistanceComputer*>(dc.get());
|
|
252
|
+
FAISS_THROW_IF_NOT(rabitq_dc);
|
|
253
|
+
}
|
|
254
|
+
rabitq_dc->set_centroid(reconstructed_centroid.data());
|
|
282
255
|
dc->set_query(query_vector.data());
|
|
283
|
-
|
|
284
|
-
// Try to cast to RaBitQDistanceComputer for multi-bit support
|
|
285
|
-
rabitq_dc = dynamic_cast<RaBitQDistanceComputer*>(dc.get());
|
|
286
256
|
}
|
|
287
257
|
}
|
|
288
258
|
};
|
|
@@ -309,12 +279,12 @@ void IndexIVFRaBitQ::reconstruct_from_offset(
|
|
|
309
279
|
int64_t list_no,
|
|
310
280
|
int64_t offset,
|
|
311
281
|
float* recons) const {
|
|
312
|
-
|
|
282
|
+
InvertedLists::ScopedCodes sc(invlists, list_no, offset);
|
|
313
283
|
|
|
314
284
|
std::vector<float> centroid(d);
|
|
315
285
|
quantizer->reconstruct(list_no, centroid.data());
|
|
316
286
|
|
|
317
|
-
rabitq.decode_core(
|
|
287
|
+
rabitq.decode_core(sc.get(), recons, 1, centroid.data());
|
|
318
288
|
}
|
|
319
289
|
|
|
320
290
|
void IndexIVFRaBitQ::sa_decode(idx_t n, const uint8_t* codes, float* x) const {
|
|
@@ -357,26 +327,17 @@ float IVFRaBitDistanceComputer::operator()(idx_t i) {
|
|
|
357
327
|
uint64_t list_no = lo_listno(lo);
|
|
358
328
|
uint64_t offset = lo_offset(lo);
|
|
359
329
|
|
|
360
|
-
|
|
330
|
+
InvertedLists::ScopedCodes sc(parent->invlists, list_no, offset);
|
|
361
331
|
|
|
362
332
|
// ok, we know the appropriate cluster that we need
|
|
363
333
|
std::vector<float> centroid(parent->d);
|
|
364
334
|
parent->quantizer->reconstruct(list_no, centroid.data());
|
|
365
335
|
|
|
366
|
-
// compute the distance
|
|
367
|
-
float distance = 0;
|
|
368
|
-
|
|
369
336
|
std::unique_ptr<FlatCodesDistanceComputer> dc(
|
|
370
337
|
parent->rabitq.get_distance_computer(
|
|
371
338
|
parent->qb, centroid.data(), /*centered=*/false));
|
|
372
339
|
dc->set_query(q);
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
// deallocate
|
|
376
|
-
parent->invlists->release_codes(list_no, code);
|
|
377
|
-
|
|
378
|
-
// done
|
|
379
|
-
return distance;
|
|
340
|
+
return dc->distance_to_code(sc.get());
|
|
380
341
|
}
|
|
381
342
|
|
|
382
343
|
float IVFRaBitDistanceComputer::symmetric_dis(idx_t /*i*/, idx_t /*j*/) {
|
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
#include <faiss/impl/ResultHandler.h>
|
|
20
20
|
#include <faiss/impl/fast_scan/FastScanDistancePostProcessing.h>
|
|
21
21
|
#include <faiss/impl/fast_scan/fast_scan.h>
|
|
22
|
+
#include <faiss/impl/simd_dispatch.h>
|
|
22
23
|
#include <faiss/invlists/BlockInvertedLists.h>
|
|
23
24
|
#include <faiss/utils/distances.h>
|
|
25
|
+
#include <faiss/utils/rabitq_simd.h>
|
|
24
26
|
#include <faiss/utils/utils.h>
|
|
25
27
|
|
|
26
28
|
namespace faiss {
|
|
@@ -28,6 +30,7 @@ namespace faiss {
|
|
|
28
30
|
// Import shared utilities from RaBitQUtils
|
|
29
31
|
using rabitq_utils::ExtraBitsFactors;
|
|
30
32
|
using rabitq_utils::QueryFactorsData;
|
|
33
|
+
using rabitq_utils::round_nonnegative_to_uint16;
|
|
31
34
|
using rabitq_utils::SignBitFactors;
|
|
32
35
|
using rabitq_utils::SignBitFactorsWithError;
|
|
33
36
|
|
|
@@ -62,8 +65,9 @@ IndexIVFRaBitQFastScan::IndexIVFRaBitQFastScan(
|
|
|
62
65
|
metric == METRIC_L2 || metric == METRIC_INNER_PRODUCT,
|
|
63
66
|
"RaBitQ only supports L2 and Inner Product metrics");
|
|
64
67
|
FAISS_THROW_IF_NOT_MSG(
|
|
65
|
-
bbs_in % 32 == 0,
|
|
66
|
-
|
|
68
|
+
bbs_in > 0 && bbs_in % 32 == 0,
|
|
69
|
+
"Batch size must be positive and a multiple of 32");
|
|
70
|
+
FAISS_THROW_IF_MSG(quantizer_in == nullptr, "Quantizer cannot be null");
|
|
67
71
|
|
|
68
72
|
by_residual = true;
|
|
69
73
|
qb = 8; // RaBitQ quantization bits
|
|
@@ -91,10 +95,12 @@ IndexIVFRaBitQFastScan::IndexIVFRaBitQFastScan(
|
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
|
|
94
|
-
// Constructor that converts an existing IndexIVFRaBitQ to FastScan format
|
|
98
|
+
// Constructor that converts an existing IndexIVFRaBitQ to FastScan format.
|
|
99
|
+
// Like other IVF FastScan conversion constructors, this borrows orig's
|
|
100
|
+
// quantizer and orig_invlists; orig must outlive the converted index.
|
|
95
101
|
IndexIVFRaBitQFastScan::IndexIVFRaBitQFastScan(
|
|
96
102
|
const IndexIVFRaBitQ& orig,
|
|
97
|
-
int
|
|
103
|
+
int bbs_in)
|
|
98
104
|
: IndexIVFFastScan(
|
|
99
105
|
orig.quantizer,
|
|
100
106
|
orig.d,
|
|
@@ -102,7 +108,93 @@ IndexIVFRaBitQFastScan::IndexIVFRaBitQFastScan(
|
|
|
102
108
|
0,
|
|
103
109
|
orig.metric_type,
|
|
104
110
|
false),
|
|
105
|
-
rabitq(orig.rabitq) {
|
|
111
|
+
rabitq(orig.rabitq) {
|
|
112
|
+
FAISS_THROW_IF_NOT_MSG(orig.d > 0, "Dimension must be positive");
|
|
113
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
114
|
+
orig.metric_type == METRIC_L2 ||
|
|
115
|
+
orig.metric_type == METRIC_INNER_PRODUCT,
|
|
116
|
+
"RaBitQ only supports L2 and Inner Product metrics");
|
|
117
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
118
|
+
bbs_in > 0 && bbs_in % 32 == 0,
|
|
119
|
+
"Batch size must be positive and a multiple of 32");
|
|
120
|
+
FAISS_THROW_IF_NOT_MSG(orig.invlists != nullptr, "Source invlists null");
|
|
121
|
+
|
|
122
|
+
by_residual = true;
|
|
123
|
+
qb = orig.qb;
|
|
124
|
+
centered = false;
|
|
125
|
+
|
|
126
|
+
const size_t M_fastscan = (orig.d + 3) / 4;
|
|
127
|
+
constexpr size_t nbits_fastscan = 4;
|
|
128
|
+
|
|
129
|
+
this->bbs = bbs_in;
|
|
130
|
+
this->fine_quantizer = &rabitq;
|
|
131
|
+
this->M = M_fastscan;
|
|
132
|
+
this->nbits = nbits_fastscan;
|
|
133
|
+
this->ksub = (1 << nbits_fastscan);
|
|
134
|
+
this->M2 = roundup(M_fastscan, 2);
|
|
135
|
+
|
|
136
|
+
const size_t bit_pattern_size = (d + 7) / 8;
|
|
137
|
+
const size_t storage_size = compute_per_vector_storage_size();
|
|
138
|
+
this->code_size = bit_pattern_size + storage_size;
|
|
139
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
140
|
+
orig.code_size == code_size,
|
|
141
|
+
"Source IndexIVFRaBitQ code size is incompatible");
|
|
142
|
+
|
|
143
|
+
ntotal = orig.ntotal;
|
|
144
|
+
is_trained = orig.is_trained;
|
|
145
|
+
nprobe = orig.nprobe;
|
|
146
|
+
|
|
147
|
+
replace_invlists(new BlockInvertedLists(nlist, get_CodePacker()), true);
|
|
148
|
+
|
|
149
|
+
#pragma omp parallel for if (nlist > 100)
|
|
150
|
+
for (idx_t list_no = 0; list_no < static_cast<idx_t>(nlist); list_no++) {
|
|
151
|
+
const size_t nb = orig.invlists->list_size(list_no);
|
|
152
|
+
if (nb == 0) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
AlignedTable<uint8_t> flat_codes(nb * code_size);
|
|
157
|
+
memset(flat_codes.get(), 0, nb * code_size);
|
|
158
|
+
|
|
159
|
+
InvertedLists::ScopedCodes orig_codes(orig.invlists, list_no);
|
|
160
|
+
for (size_t i = 0; i < nb; i++) {
|
|
161
|
+
const uint8_t* orig_code = orig_codes.get() + i * orig.code_size;
|
|
162
|
+
uint8_t* fs_code = flat_codes.get() + i * code_size;
|
|
163
|
+
|
|
164
|
+
for (size_t j = 0; j < static_cast<size_t>(d); j++) {
|
|
165
|
+
const size_t orig_byte_idx = j / 8;
|
|
166
|
+
const size_t orig_bit_offset = j % 8;
|
|
167
|
+
const bool bit_value =
|
|
168
|
+
(orig_code[orig_byte_idx] >> orig_bit_offset) & 1;
|
|
169
|
+
if (bit_value) {
|
|
170
|
+
rabitq_utils::set_bit_fastscan(fs_code, j);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
memcpy(fs_code + bit_pattern_size,
|
|
175
|
+
orig_code + bit_pattern_size,
|
|
176
|
+
storage_size);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
std::unique_ptr<CodePacker> packer(get_CodePacker());
|
|
180
|
+
const size_t nb2 = roundup(nb, bbs);
|
|
181
|
+
AlignedTable<uint8_t> block_codes(nb2 / bbs * packer->block_size);
|
|
182
|
+
memset(block_codes.get(), 0, block_codes.size());
|
|
183
|
+
|
|
184
|
+
for (size_t i = 0; i < nb; i++) {
|
|
185
|
+
packer->pack_1(
|
|
186
|
+
flat_codes.get() + i * code_size, i, block_codes.get());
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
invlists->add_entries(
|
|
190
|
+
list_no,
|
|
191
|
+
nb,
|
|
192
|
+
InvertedLists::ScopedIds(orig.invlists, list_no).get(),
|
|
193
|
+
block_codes.get());
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
orig_invlists = orig.invlists;
|
|
197
|
+
}
|
|
106
198
|
|
|
107
199
|
size_t IndexIVFRaBitQFastScan::compute_per_vector_storage_size() const {
|
|
108
200
|
return rabitq_utils::compute_per_vector_storage_size(rabitq.nb_bits, d);
|
|
@@ -161,8 +253,10 @@ void IndexIVFRaBitQFastScan::train_encoder(
|
|
|
161
253
|
const float* x,
|
|
162
254
|
const idx_t* assign) {
|
|
163
255
|
FAISS_THROW_IF_NOT(n > 0);
|
|
164
|
-
FAISS_THROW_IF_NOT(x
|
|
165
|
-
|
|
256
|
+
FAISS_THROW_IF_NOT(x);
|
|
257
|
+
FAISS_THROW_IF_MSG(
|
|
258
|
+
assign == nullptr && by_residual,
|
|
259
|
+
"assign is required when by_residual is set");
|
|
166
260
|
|
|
167
261
|
rabitq.train(n, x);
|
|
168
262
|
is_trained = true;
|
|
@@ -176,9 +270,9 @@ void IndexIVFRaBitQFastScan::encode_vectors(
|
|
|
176
270
|
uint8_t* codes,
|
|
177
271
|
bool include_listnos) const {
|
|
178
272
|
FAISS_THROW_IF_NOT(n > 0);
|
|
179
|
-
FAISS_THROW_IF_NOT(x
|
|
180
|
-
FAISS_THROW_IF_NOT(list_nos
|
|
181
|
-
FAISS_THROW_IF_NOT(codes
|
|
273
|
+
FAISS_THROW_IF_NOT(x);
|
|
274
|
+
FAISS_THROW_IF_NOT(list_nos);
|
|
275
|
+
FAISS_THROW_IF_NOT(codes);
|
|
182
276
|
FAISS_THROW_IF_NOT(is_trained);
|
|
183
277
|
|
|
184
278
|
size_t coarse_size = include_listnos ? coarse_code_size() : 0;
|
|
@@ -416,9 +510,9 @@ void IndexIVFRaBitQFastScan::search_preassigned(
|
|
|
416
510
|
IndexIVFStats* stats) const {
|
|
417
511
|
FAISS_THROW_IF_NOT(is_trained);
|
|
418
512
|
FAISS_THROW_IF_NOT(k > 0);
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
513
|
+
FAISS_THROW_IF_MSG(
|
|
514
|
+
store_pairs, "store_pairs not supported for RaBitQFastScan");
|
|
515
|
+
FAISS_THROW_IF_MSG(stats, "stats not supported for this index");
|
|
422
516
|
|
|
423
517
|
size_t cur_nprobe = this->nprobe;
|
|
424
518
|
uint8_t used_qb = qb;
|
|
@@ -453,6 +547,7 @@ void IndexIVFRaBitQFastScan::compute_LUT(
|
|
|
453
547
|
const FastScanDistancePostProcessing& context) const {
|
|
454
548
|
FAISS_THROW_IF_NOT(is_trained);
|
|
455
549
|
FAISS_THROW_IF_NOT(by_residual);
|
|
550
|
+
FAISS_ASSERT(ksub == 16);
|
|
456
551
|
|
|
457
552
|
// Use overridden qb/centered from context if provided, else index defaults
|
|
458
553
|
const uint8_t used_qb = context.qb > 0 ? context.qb : qb;
|
|
@@ -515,6 +610,7 @@ void IndexIVFRaBitQFastScan::compute_LUT_uint8(
|
|
|
515
610
|
const FastScanDistancePostProcessing& context) const {
|
|
516
611
|
FAISS_THROW_IF_NOT(is_trained);
|
|
517
612
|
FAISS_THROW_IF_NOT(by_residual);
|
|
613
|
+
FAISS_ASSERT(ksub == 16);
|
|
518
614
|
|
|
519
615
|
const uint8_t used_qb = context.qb > 0 ? context.qb : qb;
|
|
520
616
|
const bool used_centered = context.qb > 0 ? context.centered : centered;
|
|
@@ -572,45 +668,53 @@ void IndexIVFRaBitQFastScan::compute_LUT_uint8(
|
|
|
572
668
|
float glob_max_span = -HUGE_VAL;
|
|
573
669
|
float glob_max_dis = -HUGE_VAL;
|
|
574
670
|
float glob_b = HUGE_VAL;
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
671
|
+
float a;
|
|
672
|
+
with_selected_simd_levels<rabitq::RABITQ_QUANTIZATION_SIMD_LEVELS>(
|
|
673
|
+
[&]<SIMDLevel SL>() {
|
|
674
|
+
for (size_t j2 = 0; j2 < cur_nprobe; j2++) {
|
|
675
|
+
float b_j = 0;
|
|
676
|
+
float span_j = 0;
|
|
677
|
+
for (size_t m = 0; m < M; m++) {
|
|
678
|
+
const float* tab =
|
|
679
|
+
lut_float.get() + j2 * dim12 + m * ksub;
|
|
680
|
+
float mn, mx;
|
|
681
|
+
rabitq::lut_minmax_16<SL>(tab, mn, mx);
|
|
682
|
+
all_mins[j2 * M + m] = mn;
|
|
683
|
+
float span = mx - mn;
|
|
684
|
+
glob_max_span = std::max(glob_max_span, span);
|
|
685
|
+
b_j += mn;
|
|
686
|
+
span_j += span;
|
|
687
|
+
}
|
|
688
|
+
probe_b[j2] = b_j;
|
|
689
|
+
glob_max_dis = std::max(glob_max_dis, span_j);
|
|
690
|
+
glob_b = std::min(glob_b, b_j);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
a = std::min(
|
|
694
|
+
255.0f / glob_max_span,
|
|
695
|
+
65535.0f / glob_max_dis);
|
|
696
|
+
|
|
697
|
+
// Second pass: quantize LUT and compute biasq.
|
|
698
|
+
uint8_t* out_base =
|
|
699
|
+
dis_tables.get() + i * cur_nprobe * dim12_2;
|
|
700
|
+
uint16_t* bq = biases.get() + i * cur_nprobe;
|
|
701
|
+
for (size_t j2 = 0; j2 < cur_nprobe; j2++) {
|
|
702
|
+
for (size_t m = 0; m < M; m++) {
|
|
703
|
+
const float* tab =
|
|
704
|
+
lut_float.get() + j2 * dim12 + m * ksub;
|
|
705
|
+
const float mn = all_mins[j2 * M + m];
|
|
706
|
+
uint8_t* out =
|
|
707
|
+
out_base + j2 * dim12_2 + m * ksub;
|
|
708
|
+
rabitq::lut_quantize_16_to_uint8<SL>(
|
|
709
|
+
tab, mn, a, out);
|
|
710
|
+
}
|
|
711
|
+
memset(out_base + j2 * dim12_2 + M * ksub,
|
|
712
|
+
0,
|
|
713
|
+
(M2 - M) * ksub);
|
|
714
|
+
bq[j2] = round_nonnegative_to_uint16(
|
|
715
|
+
a * (probe_b[j2] - glob_b));
|
|
716
|
+
}
|
|
717
|
+
});
|
|
614
718
|
normalizers[2 * i] = a;
|
|
615
719
|
normalizers[2 * i + 1] = glob_b;
|
|
616
720
|
}
|
|
@@ -676,8 +780,8 @@ void IndexIVFRaBitQFastScan::sa_decode(idx_t n, const uint8_t* bytes, float* x)
|
|
|
676
780
|
const {
|
|
677
781
|
FAISS_THROW_IF_NOT(is_trained);
|
|
678
782
|
FAISS_THROW_IF_NOT(n > 0);
|
|
679
|
-
FAISS_THROW_IF_NOT(bytes
|
|
680
|
-
FAISS_THROW_IF_NOT(x
|
|
783
|
+
FAISS_THROW_IF_NOT(bytes);
|
|
784
|
+
FAISS_THROW_IF_NOT(x);
|
|
681
785
|
|
|
682
786
|
size_t coarse_size = coarse_code_size();
|
|
683
787
|
size_t total_code_size = code_size + coarse_size;
|
|
@@ -826,35 +930,35 @@ struct IVFRaBitQFastScanScanner : InvertedListScanner {
|
|
|
826
930
|
const size_t M = index.M;
|
|
827
931
|
const size_t M2 = index.M2;
|
|
828
932
|
const size_t ksub = index.ksub;
|
|
933
|
+
FAISS_ASSERT(ksub == 16);
|
|
829
934
|
|
|
830
935
|
float max_span = -HUGE_VAL;
|
|
831
936
|
float max_dis = 0;
|
|
832
937
|
float b = 0;
|
|
833
938
|
float* mins = mins_buf.data();
|
|
834
939
|
|
|
835
|
-
|
|
836
|
-
const float* tab = lut_float.get() + m * ksub;
|
|
837
|
-
float mn = tab[0], mx = tab[0];
|
|
838
|
-
for (size_t s = 1; s < ksub; s++) {
|
|
839
|
-
mn = std::min(mn, tab[s]);
|
|
840
|
-
mx = std::max(mx, tab[s]);
|
|
841
|
-
}
|
|
842
|
-
mins[m] = mn;
|
|
843
|
-
float span = mx - mn;
|
|
844
|
-
max_span = std::max(max_span, span);
|
|
845
|
-
max_dis += span;
|
|
846
|
-
b += mn;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
float a = std::min(255.0f / max_span, 65535.0f / max_dis);
|
|
940
|
+
float a;
|
|
850
941
|
uint8_t* out = dis_tables.get();
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
942
|
+
with_selected_simd_levels<rabitq::RABITQ_QUANTIZATION_SIMD_LEVELS>(
|
|
943
|
+
[&]<SIMDLevel SL>() {
|
|
944
|
+
for (size_t m = 0; m < M; m++) {
|
|
945
|
+
const float* tab = lut_float.get() + m * ksub;
|
|
946
|
+
float mn, mx;
|
|
947
|
+
rabitq::lut_minmax_16<SL>(tab, mn, mx);
|
|
948
|
+
mins[m] = mn;
|
|
949
|
+
float span = mx - mn;
|
|
950
|
+
max_span = std::max(max_span, span);
|
|
951
|
+
max_dis += span;
|
|
952
|
+
b += mn;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
a = std::min(255.0f / max_span, 65535.0f / max_dis);
|
|
956
|
+
for (size_t m = 0; m < M; m++) {
|
|
957
|
+
const float* tab = lut_float.get() + m * ksub;
|
|
958
|
+
rabitq::lut_quantize_16_to_uint8<SL>(
|
|
959
|
+
tab, mins[m], a, out + m * ksub);
|
|
960
|
+
}
|
|
961
|
+
});
|
|
858
962
|
memset(out + M * ksub, 0, (M2 - M) * ksub);
|
|
859
963
|
biases[0] = 0;
|
|
860
964
|
normalizers[0] = a;
|
|
@@ -267,11 +267,12 @@ void IVFRaBitQHeapHandler<C, SL>::handle(
|
|
|
267
267
|
}
|
|
268
268
|
const size_t max_positions = std::min<size_t>(32, this->ntotal - idx_base);
|
|
269
269
|
|
|
270
|
-
// Hoist aux pointer base out of loop:
|
|
271
|
-
// the
|
|
272
|
-
// varies.
|
|
270
|
+
// Hoist aux pointer base out of loop: it points at this 32-lane sub-block's
|
|
271
|
+
// factors, i.e. the bbs block base plus the loop-invariant intra-block
|
|
272
|
+
// offset ((idx_base % bbs)). Only the per-element j term varies below.
|
|
273
273
|
const uint8_t* aux_base = this->list_codes_ptr +
|
|
274
|
-
(idx_base / index->bbs) * full_block_size + packed_block_size
|
|
274
|
+
(idx_base / index->bbs) * full_block_size + packed_block_size +
|
|
275
|
+
(idx_base % index->bbs) * storage_size;
|
|
275
276
|
|
|
276
277
|
// Cache index fields used in the inner loop.
|
|
277
278
|
// Use overridden qb/centered from context if provided, else index defaults.
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
29
29
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
30
30
|
#include <faiss/impl/binary_hamming/IndexIVFSpectralHash_impl.h>
|
|
31
|
-
#include <faiss/utils/hamming_distance/hamming_computer-generic.h>
|
|
32
31
|
#undef THE_SIMD_LEVEL
|
|
33
32
|
|
|
34
33
|
namespace faiss {
|
|
@@ -88,7 +87,7 @@ void IndexIVFSpectralHash::train_encoder(
|
|
|
88
87
|
if (!vt->is_trained) {
|
|
89
88
|
vt->train(n, x);
|
|
90
89
|
}
|
|
91
|
-
|
|
90
|
+
FAISS_THROW_IF_MSG(by_residual, "by_residual not supported for this index");
|
|
92
91
|
|
|
93
92
|
if (threshold_type == Thresh_global) {
|
|
94
93
|
// nothing to do
|
|
@@ -185,7 +184,7 @@ void IndexIVFSpectralHash::encode_vectors(
|
|
|
185
184
|
uint8_t* codes,
|
|
186
185
|
bool include_listnos) const {
|
|
187
186
|
FAISS_THROW_IF_NOT(is_trained);
|
|
188
|
-
|
|
187
|
+
FAISS_THROW_IF_MSG(by_residual, "by_residual not supported for this index");
|
|
189
188
|
float freq = 2.0 / period;
|
|
190
189
|
size_t coarse_size = include_listnos ? coarse_code_size() : 0;
|
|
191
190
|
|
|
@@ -222,7 +221,7 @@ InvertedListScanner* IndexIVFSpectralHash::get_InvertedListScanner(
|
|
|
222
221
|
bool store_pairs,
|
|
223
222
|
const IDSelector* sel,
|
|
224
223
|
const IVFSearchParameters*) const {
|
|
225
|
-
|
|
224
|
+
FAISS_THROW_IF_MSG(sel, "id selector not supported for this index");
|
|
226
225
|
return with_simd_level([&]<SIMDLevel SL>() {
|
|
227
226
|
return make_spectral_hash_scanner_fixSL<SL>(
|
|
228
227
|
code_size, this, store_pairs);
|
|
@@ -254,8 +253,11 @@ void IndexIVFSpectralHash::replace_vt(IndexPreTransform* encoder, bool own) {
|
|
|
254
253
|
auto sub_index = dynamic_cast<IndexLSH*>(encoder->index);
|
|
255
254
|
FAISS_THROW_IF_NOT_MSG(sub_index, "final index should be LSH");
|
|
256
255
|
FAISS_THROW_IF_NOT(sub_index->nbits == nbit);
|
|
257
|
-
|
|
258
|
-
|
|
256
|
+
FAISS_THROW_IF_MSG(
|
|
257
|
+
sub_index->rotate_data, "LSH sub-index must not rotate data");
|
|
258
|
+
FAISS_THROW_IF_MSG(
|
|
259
|
+
sub_index->train_thresholds,
|
|
260
|
+
"LSH sub-index thresholds must already be trained");
|
|
259
261
|
replace_vt(encoder->chain[0], own);
|
|
260
262
|
}
|
|
261
263
|
|
|
@@ -119,8 +119,7 @@ void IndexLSH::search(
|
|
|
119
119
|
float* distances,
|
|
120
120
|
idx_t* labels,
|
|
121
121
|
const SearchParameters* params) const {
|
|
122
|
-
|
|
123
|
-
!params, "search params not supported for this index");
|
|
122
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
124
123
|
FAISS_THROW_IF_NOT(k > 0);
|
|
125
124
|
FAISS_THROW_IF_NOT(is_trained);
|
|
126
125
|
const float* xt = apply_preprocess(n, x);
|
|
@@ -151,7 +150,7 @@ void IndexLSH::transfer_thresholds(LinearTransform* vt) {
|
|
|
151
150
|
vt->b.resize(nbits, 0);
|
|
152
151
|
vt->have_bias = true;
|
|
153
152
|
}
|
|
154
|
-
|
|
153
|
+
FAISS_THROW_IF_MSG(vt->b.empty(), "bias vector must not be empty");
|
|
155
154
|
for (int i = 0; i < nbits; i++) {
|
|
156
155
|
vt->b[i] -= thresholds[i];
|
|
157
156
|
}
|
|
@@ -26,6 +26,11 @@ IndexLattice::IndexLattice(idx_t d_in, int nsq_in, int scale_nbit_in, int r2)
|
|
|
26
26
|
lattice_nbit = 0;
|
|
27
27
|
while (!(((uint64_t)1 << lattice_nbit) >= zn_sphere_codec.nv)) {
|
|
28
28
|
lattice_nbit++;
|
|
29
|
+
FAISS_THROW_IF_NOT_FMT(
|
|
30
|
+
lattice_nbit < 64,
|
|
31
|
+
"IndexLattice: nv=%zu too large, lattice code would exceed "
|
|
32
|
+
"63 bits (likely corrupt r2/dsq)",
|
|
33
|
+
(size_t)zn_sphere_codec.nv);
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
int total_nbit = (lattice_nbit + scale_nbit_in) * nsq_in;
|
|
@@ -101,8 +101,7 @@ void IndexNNDescent::search(
|
|
|
101
101
|
float* distances,
|
|
102
102
|
idx_t* labels,
|
|
103
103
|
const SearchParameters* params) const {
|
|
104
|
-
|
|
105
|
-
!params, "search params not supported for this index");
|
|
104
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
106
105
|
FAISS_THROW_IF_NOT_MSG(
|
|
107
106
|
storage,
|
|
108
107
|
"Please use IndexNNDescentFlat (or variants) "
|
|
@@ -126,7 +125,7 @@ void IndexNNDescent::search(
|
|
|
126
125
|
std::unique_ptr<DistanceComputer> dis;
|
|
127
126
|
std::unique_ptr<VisitedTable> vt;
|
|
128
127
|
try {
|
|
129
|
-
vt =
|
|
128
|
+
vt = VisitedTable::create(ntotal);
|
|
130
129
|
dis.reset(storage_distance_computer(storage));
|
|
131
130
|
} catch (...) {
|
|
132
131
|
omp_capture_exception(ex, [&] { interrupt = true; });
|
|
@@ -183,11 +182,19 @@ void IndexNNDescent::add(idx_t n, const float* x) {
|
|
|
183
182
|
|
|
184
183
|
void IndexNNDescent::reset() {
|
|
185
184
|
nndescent.reset();
|
|
185
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
186
|
+
storage,
|
|
187
|
+
"Please use IndexNNDescentFlat (or variants) "
|
|
188
|
+
"instead of IndexNNDescent directly");
|
|
186
189
|
storage->reset();
|
|
187
190
|
ntotal = 0;
|
|
188
191
|
}
|
|
189
192
|
|
|
190
193
|
void IndexNNDescent::reconstruct(idx_t key, float* recons) const {
|
|
194
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
195
|
+
storage,
|
|
196
|
+
"Please use IndexNNDescentFlat (or variants) "
|
|
197
|
+
"instead of IndexNNDescent directly");
|
|
191
198
|
storage->reconstruct(key, recons);
|
|
192
199
|
}
|
|
193
200
|
|
|
@@ -62,8 +62,7 @@ void IndexNSG::search(
|
|
|
62
62
|
float* distances,
|
|
63
63
|
idx_t* labels,
|
|
64
64
|
const SearchParameters* params) const {
|
|
65
|
-
|
|
66
|
-
!params, "search params not supported for this index");
|
|
65
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
67
66
|
FAISS_THROW_IF_NOT_MSG(
|
|
68
67
|
storage,
|
|
69
68
|
"Please use IndexNSGFlat (or variants) instead of IndexNSG directly");
|
|
@@ -81,8 +80,7 @@ void IndexNSG::search(
|
|
|
81
80
|
std::unique_ptr<DistanceComputer> dis;
|
|
82
81
|
std::unique_ptr<VisitedTable> vt;
|
|
83
82
|
try {
|
|
84
|
-
vt =
|
|
85
|
-
ntotal, nsg.use_visited_hashset);
|
|
83
|
+
vt = VisitedTable::create(ntotal, nsg.use_visited_hashset);
|
|
86
84
|
dis.reset(storage_distance_computer(storage));
|
|
87
85
|
} catch (...) {
|
|
88
86
|
omp_capture_exception(ex, [&] { interrupt = true; });
|
|
@@ -246,12 +244,18 @@ void IndexNSG::add(idx_t n, const float* x) {
|
|
|
246
244
|
|
|
247
245
|
void IndexNSG::reset() {
|
|
248
246
|
nsg.reset();
|
|
247
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
248
|
+
storage,
|
|
249
|
+
"Please use IndexNSGFlat (or variants) instead of IndexNSG directly");
|
|
249
250
|
storage->reset();
|
|
250
251
|
ntotal = 0;
|
|
251
252
|
is_built = false;
|
|
252
253
|
}
|
|
253
254
|
|
|
254
255
|
void IndexNSG::reconstruct(idx_t key, float* recons) const {
|
|
256
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
257
|
+
storage,
|
|
258
|
+
"Please use IndexNSGFlat (or variants) instead of IndexNSG directly");
|
|
255
259
|
storage->reconstruct(key, recons);
|
|
256
260
|
}
|
|
257
261
|
|