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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0ab0ef0079ca7056c6d303b95882757645a81bee9b4c13862f4337dbec1b105a
|
|
4
|
+
data.tar.gz: d61339d723153ed333a6719001de98fa1742606334684b0f7db26f26ad001b09
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20ce33982905751c82f05241b94ca500b241ac15f18245e8e14dad29d2fe5f162c7d4fe4e5441e92f79e06eb9519538831fa2c857050e6b3ea8ad5d0b8e63366
|
|
7
|
+
data.tar.gz: cfd073d25d3067488fdde88e06c5c68eeec6840ea57b9e6222129f4594279a27148b62361bcbd0dcc57727053acd35e4f202558adef03de648d0c8179f05ce07
|
data/CHANGELOG.md
CHANGED
data/lib/faiss/version.rb
CHANGED
|
@@ -45,6 +45,8 @@ void AutoTuneCriterion::set_groundtruth(
|
|
|
45
45
|
gt_D.resize(nq * gt_nnn_in);
|
|
46
46
|
memcpy(gt_D.data(), gt_D_in, sizeof(gt_D[0]) * nq * gt_nnn_in);
|
|
47
47
|
}
|
|
48
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
49
|
+
gt_I_in != nullptr, "set_groundtruth: gt_I must be non-null");
|
|
48
50
|
gt_I.resize(nq * gt_nnn_in);
|
|
49
51
|
memcpy(gt_I.data(), gt_I_in, sizeof(gt_I[0]) * nq * gt_nnn_in);
|
|
50
52
|
}
|
|
@@ -148,7 +150,7 @@ bool OperatingPoints::add(
|
|
|
148
150
|
}
|
|
149
151
|
// remove non-optimal points from array
|
|
150
152
|
for (size_t i = a.size() - 1; i > 0; --i) {
|
|
151
|
-
if (a[i].t
|
|
153
|
+
if (a[i].t <= a[i - 1].t) {
|
|
152
154
|
a.erase(a.begin() + (i - 1));
|
|
153
155
|
}
|
|
154
156
|
}
|
|
@@ -367,7 +367,7 @@ void Clustering::train_encoded(
|
|
|
367
367
|
? std::numeric_limits<double>::max()
|
|
368
368
|
: std::abs(prev_obj - obj) / std::abs(prev_obj);
|
|
369
369
|
|
|
370
|
-
if (change
|
|
370
|
+
if (change <= early_stop_threshold) {
|
|
371
371
|
if (verbose) {
|
|
372
372
|
printf("\n Converged at iteration %d: "
|
|
373
373
|
"objective did not change\n",
|
|
@@ -439,6 +439,14 @@ float kmeans_clustering(
|
|
|
439
439
|
size_t k,
|
|
440
440
|
const float* x,
|
|
441
441
|
float* centroids) {
|
|
442
|
+
FAISS_THROW_IF_NOT_FMT(
|
|
443
|
+
d <= static_cast<size_t>(std::numeric_limits<int>::max()),
|
|
444
|
+
"kmeans_clustering: d=%zu exceeds INT_MAX",
|
|
445
|
+
d);
|
|
446
|
+
FAISS_THROW_IF_NOT_FMT(
|
|
447
|
+
k <= static_cast<size_t>(std::numeric_limits<int>::max()),
|
|
448
|
+
"kmeans_clustering: k=%zu exceeds INT_MAX",
|
|
449
|
+
k);
|
|
442
450
|
Clustering clus(static_cast<int>(d), static_cast<int>(k));
|
|
443
451
|
clus.verbose = d * n * k > (size_t(1) << 30);
|
|
444
452
|
// display logs if > 1Gflop per iteration
|
|
@@ -592,8 +592,12 @@ void handle_ivf(
|
|
|
592
592
|
static_cast<faiss::IndexIVF*>(faiss::clone_index(clone));
|
|
593
593
|
if (generate_ids) {
|
|
594
594
|
// Assume the quantizer does not natively support add_with_ids.
|
|
595
|
-
|
|
596
|
-
|
|
595
|
+
// The IDMap wraps the cloned quantizer; own_fields makes it delete
|
|
596
|
+
// that quantizer when sharded_index (which owns the IDMap) is
|
|
597
|
+
// freed.
|
|
598
|
+
auto* id_quantizer = new IndexIDMap2(sharded_index->quantizer);
|
|
599
|
+
id_quantizer->own_fields = true;
|
|
600
|
+
sharded_index->quantizer = id_quantizer;
|
|
597
601
|
sharded_index->quantizer->add_with_ids(
|
|
598
602
|
sharded_centroids[i].size() / index->quantizer->d,
|
|
599
603
|
sharded_centroids[i].data(),
|
|
@@ -615,6 +619,7 @@ void handle_ivf(
|
|
|
615
619
|
faiss::write_index(sharded_index, fname);
|
|
616
620
|
delete sharded_index;
|
|
617
621
|
}
|
|
622
|
+
delete clone;
|
|
618
623
|
}
|
|
619
624
|
|
|
620
625
|
void handle_binary_ivf(
|
|
@@ -650,8 +655,13 @@ void handle_binary_ivf(
|
|
|
650
655
|
faiss::clone_binary_index(clone));
|
|
651
656
|
if (generate_ids) {
|
|
652
657
|
// Assume the quantizer does not natively support add_with_ids.
|
|
653
|
-
|
|
658
|
+
// The IDMap wraps the cloned quantizer; own_fields makes it delete
|
|
659
|
+
// that quantizer when sharded_index (which owns the IDMap) is
|
|
660
|
+
// freed.
|
|
661
|
+
auto* id_quantizer =
|
|
654
662
|
new IndexBinaryIDMap2(sharded_index->quantizer);
|
|
663
|
+
id_quantizer->own_fields = true;
|
|
664
|
+
sharded_index->quantizer = id_quantizer;
|
|
655
665
|
sharded_index->quantizer->add_with_ids(
|
|
656
666
|
sharded_centroids[i].size() / reconstruction_size,
|
|
657
667
|
sharded_centroids[i].data(),
|
|
@@ -673,6 +683,7 @@ void handle_binary_ivf(
|
|
|
673
683
|
faiss::write_index_binary(sharded_index, fname);
|
|
674
684
|
delete sharded_index;
|
|
675
685
|
}
|
|
686
|
+
delete clone;
|
|
676
687
|
}
|
|
677
688
|
|
|
678
689
|
template <typename IndexType>
|
data/vendor/faiss/faiss/Index.h
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
#include <cstdio>
|
|
17
17
|
|
|
18
18
|
#define FAISS_VERSION_MAJOR 1
|
|
19
|
-
#define FAISS_VERSION_MINOR
|
|
20
|
-
#define FAISS_VERSION_PATCH
|
|
19
|
+
#define FAISS_VERSION_MINOR 15
|
|
20
|
+
#define FAISS_VERSION_PATCH 0
|
|
21
21
|
|
|
22
22
|
// Macro to combine the version components into a single string
|
|
23
23
|
#ifndef FAISS_STRINGIFY
|
|
@@ -58,8 +58,8 @@ struct AQDistanceComputerDecompress : FlatCodesDistanceComputer {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
float symmetric_dis(idx_t i, idx_t j) final {
|
|
61
|
-
aq.decode(codes + i *
|
|
62
|
-
aq.decode(codes + j *
|
|
61
|
+
aq.decode(codes + i * code_size, tmp.data(), 1);
|
|
62
|
+
aq.decode(codes + j * code_size, tmp.data() + d, 1);
|
|
63
63
|
return vd(tmp.data(), tmp.data() + d);
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -79,7 +79,8 @@ struct AQDistanceComputerLUT : FlatCodesDistanceComputer {
|
|
|
79
79
|
|
|
80
80
|
explicit AQDistanceComputerLUT(const IndexAdditiveQuantizer& iaq)
|
|
81
81
|
: FlatCodesDistanceComputer(iaq.codes.data(), iaq.code_size),
|
|
82
|
-
LUT(iaq.aq->total_codebook_size
|
|
82
|
+
LUT(iaq.aq->total_codebook_size // Storage for LUT.
|
|
83
|
+
+ size_t(iaq.d) * 2), // tmp storage for symmetric distance.
|
|
83
84
|
aq(*iaq.aq),
|
|
84
85
|
d(iaq.d) {}
|
|
85
86
|
|
|
@@ -96,9 +97,9 @@ struct AQDistanceComputerLUT : FlatCodesDistanceComputer {
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
float symmetric_dis(idx_t i, idx_t j) final {
|
|
99
|
-
float* tmp = LUT.data();
|
|
100
|
-
aq.decode(codes + i *
|
|
101
|
-
aq.decode(codes + j *
|
|
100
|
+
float* tmp = LUT.data() + aq.total_codebook_size;
|
|
101
|
+
aq.decode(codes + i * code_size, tmp, 1);
|
|
102
|
+
aq.decode(codes + j * code_size, tmp + d, 1);
|
|
102
103
|
return fvec_L2sqr(tmp, tmp + d, d);
|
|
103
104
|
}
|
|
104
105
|
|
|
@@ -234,8 +235,7 @@ void IndexAdditiveQuantizer::search(
|
|
|
234
235
|
float* distances,
|
|
235
236
|
idx_t* labels,
|
|
236
237
|
const SearchParameters* params) const {
|
|
237
|
-
|
|
238
|
-
!params, "search params not supported for this index");
|
|
238
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
239
239
|
|
|
240
240
|
if (aq->search_type == AdditiveQuantizer::ST_decompress) {
|
|
241
241
|
with_VectorDistance(d, metric_type, metric_arg, [&](auto vd) {
|
|
@@ -458,8 +458,7 @@ void AdditiveCoarseQuantizer::search(
|
|
|
458
458
|
float* distances,
|
|
459
459
|
idx_t* labels,
|
|
460
460
|
const SearchParameters* params) const {
|
|
461
|
-
|
|
462
|
-
!params, "search params not supported for this index");
|
|
461
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
463
462
|
|
|
464
463
|
if (metric_type == METRIC_INNER_PRODUCT) {
|
|
465
464
|
aq->knn_centroids_inner_product(n, x, k, distances, labels);
|
|
@@ -36,7 +36,7 @@ void IndexAdditiveQuantizerFastScan::init(
|
|
|
36
36
|
MetricType metric,
|
|
37
37
|
int bbs_) {
|
|
38
38
|
FAISS_THROW_IF_NOT(aq_init != nullptr);
|
|
39
|
-
|
|
39
|
+
FAISS_THROW_IF_MSG(aq_init->nbits.empty(), "nbits must not be empty");
|
|
40
40
|
FAISS_THROW_IF_NOT(aq_init->nbits[0] == 4);
|
|
41
41
|
if (metric == METRIC_INNER_PRODUCT) {
|
|
42
42
|
FAISS_THROW_IF_NOT_MSG(
|
|
@@ -192,8 +192,7 @@ void IndexAdditiveQuantizerFastScan::search(
|
|
|
192
192
|
float* distances,
|
|
193
193
|
idx_t* labels,
|
|
194
194
|
const SearchParameters* params) const {
|
|
195
|
-
|
|
196
|
-
!params, "search params not supported for this index");
|
|
195
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
197
196
|
FAISS_THROW_IF_NOT(k > 0);
|
|
198
197
|
bool rescale = (rescale_norm && norm_scale > 1 && metric_type == METRIC_L2);
|
|
199
198
|
if (!rescale) {
|
|
@@ -55,8 +55,7 @@ void IndexBinaryFromFloat::search(
|
|
|
55
55
|
int32_t* distances,
|
|
56
56
|
idx_t* labels,
|
|
57
57
|
const SearchParameters* params) const {
|
|
58
|
-
|
|
59
|
-
!params, "search params not supported for this index");
|
|
58
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
60
59
|
FAISS_THROW_IF_NOT(k > 0);
|
|
61
60
|
|
|
62
61
|
constexpr idx_t bs = 32768;
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
#include <faiss/impl/ResultHandler.h>
|
|
25
25
|
#include <faiss/impl/VisitedTable.h>
|
|
26
26
|
#include <faiss/utils/Heap.h>
|
|
27
|
-
#include <faiss/utils/hamming.h>
|
|
28
27
|
#include <faiss/utils/random.h>
|
|
29
28
|
|
|
30
29
|
#include <faiss/impl/simd_dispatch.h>
|
|
@@ -36,7 +35,6 @@
|
|
|
36
35
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
37
36
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
38
37
|
#include <faiss/impl/binary_hamming/IndexBinaryHNSW_impl.h>
|
|
39
|
-
#include <faiss/utils/hamming_distance/hamming_computer-generic.h>
|
|
40
38
|
#undef THE_SIMD_LEVEL
|
|
41
39
|
|
|
42
40
|
namespace faiss {
|
|
@@ -129,7 +127,7 @@ void hnsw_add_vertices(
|
|
|
129
127
|
|
|
130
128
|
#pragma omp parallel
|
|
131
129
|
{
|
|
132
|
-
VisitedTable vt(ntotal);
|
|
130
|
+
std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
|
|
133
131
|
|
|
134
132
|
std::unique_ptr<DistanceComputer> dis(
|
|
135
133
|
index_hnsw.get_distance_computer());
|
|
@@ -147,7 +145,7 @@ void hnsw_add_vertices(
|
|
|
147
145
|
pt_level,
|
|
148
146
|
pt_id,
|
|
149
147
|
locks,
|
|
150
|
-
vt,
|
|
148
|
+
*vt,
|
|
151
149
|
index_hnsw.keep_max_size_level0 && (pt_level == 0));
|
|
152
150
|
|
|
153
151
|
if (do_display && i - i0 > prev_display + 10000) {
|
|
@@ -237,7 +235,7 @@ void IndexBinaryHNSW::search(
|
|
|
237
235
|
|
|
238
236
|
#pragma omp parallel
|
|
239
237
|
{
|
|
240
|
-
VisitedTable vt(ntotal);
|
|
238
|
+
std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
|
|
241
239
|
std::unique_ptr<DistanceComputer> dis(get_distance_computer());
|
|
242
240
|
RH::SingleResultHandler res(bres);
|
|
243
241
|
|
|
@@ -249,7 +247,7 @@ void IndexBinaryHNSW::search(
|
|
|
249
247
|
// as the index parameter. This state does not get used in the
|
|
250
248
|
// search function, as it is merely there to enable Panorama
|
|
251
249
|
// execution for IndexHNSWFlatPanorama.
|
|
252
|
-
HNSWStats stats = hnsw.search(*dis, nullptr, res, vt, params_in);
|
|
250
|
+
HNSWStats stats = hnsw.search(*dis, nullptr, res, *vt, params_in);
|
|
253
251
|
n1 += stats.n1;
|
|
254
252
|
n2 += stats.n2;
|
|
255
253
|
ndis += stats.ndis;
|
|
@@ -294,8 +292,8 @@ void IndexBinaryHNSW::reconstruct(idx_t key, uint8_t* recons) const {
|
|
|
294
292
|
|
|
295
293
|
DistanceComputer* IndexBinaryHNSW::get_distance_computer() const {
|
|
296
294
|
IndexBinaryFlat* flat_storage = dynamic_cast<IndexBinaryFlat*>(storage);
|
|
297
|
-
|
|
298
|
-
flat_storage
|
|
295
|
+
FAISS_THROW_IF_MSG(
|
|
296
|
+
flat_storage == nullptr,
|
|
299
297
|
"IndexBinaryHNSW requires IndexBinaryFlat storage");
|
|
300
298
|
return with_simd_level([&]<SIMDLevel SL>() {
|
|
301
299
|
return make_binary_hnsw_distance_computer_fixSL<SL>(
|
|
@@ -318,8 +316,8 @@ IndexBinaryHNSWCagra::IndexBinaryHNSWCagra(int d_, int M)
|
|
|
318
316
|
}
|
|
319
317
|
|
|
320
318
|
void IndexBinaryHNSWCagra::add(idx_t n, const uint8_t* x) {
|
|
321
|
-
|
|
322
|
-
|
|
319
|
+
FAISS_THROW_IF_MSG(
|
|
320
|
+
base_level_only,
|
|
323
321
|
"Cannot add vectors when base_level_only is set to True");
|
|
324
322
|
|
|
325
323
|
IndexBinaryHNSW::add(n, x);
|
|
@@ -377,7 +375,7 @@ void IndexBinaryHNSWCagra::search(
|
|
|
377
375
|
|
|
378
376
|
#pragma omp parallel
|
|
379
377
|
{
|
|
380
|
-
VisitedTable vt(ntotal);
|
|
378
|
+
std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
|
|
381
379
|
std::unique_ptr<DistanceComputer> dis(get_distance_computer());
|
|
382
380
|
HNSWStats search_stats;
|
|
383
381
|
RH::SingleResultHandler res(bres);
|
|
@@ -395,7 +393,7 @@ void IndexBinaryHNSWCagra::search(
|
|
|
395
393
|
&nearest_d[i],
|
|
396
394
|
1, // search_type
|
|
397
395
|
search_stats,
|
|
398
|
-
vt,
|
|
396
|
+
*vt,
|
|
399
397
|
params);
|
|
400
398
|
|
|
401
399
|
res.end();
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
28
28
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
29
29
|
#include <faiss/impl/binary_hamming/IndexBinaryHash_impl.h>
|
|
30
|
-
#include <faiss/utils/hamming_distance/hamming_computer-generic.h>
|
|
30
|
+
#include <faiss/utils/hamming_distance/hamming_computer-generic.h> // IWYU pragma: keep
|
|
31
31
|
#undef THE_SIMD_LEVEL
|
|
32
32
|
|
|
33
33
|
namespace faiss {
|
|
@@ -83,8 +83,7 @@ void IndexBinaryHash::range_search(
|
|
|
83
83
|
int radius,
|
|
84
84
|
RangeSearchResult* result,
|
|
85
85
|
const SearchParameters* params) const {
|
|
86
|
-
|
|
87
|
-
!params, "search params not supported for this index");
|
|
86
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
88
87
|
size_t nlist = 0, ndis = 0, n0 = 0;
|
|
89
88
|
|
|
90
89
|
#pragma omp parallel if (n > 100) reduction(+ : ndis, n0, nlist)
|
|
@@ -116,8 +115,7 @@ void IndexBinaryHash::search(
|
|
|
116
115
|
int32_t* distances,
|
|
117
116
|
idx_t* labels,
|
|
118
117
|
const SearchParameters* params) const {
|
|
119
|
-
|
|
120
|
-
!params, "search params not supported for this index");
|
|
118
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
121
119
|
FAISS_THROW_IF_NOT(k > 0);
|
|
122
120
|
|
|
123
121
|
using HeapForL2 = CMax<int32_t, idx_t>;
|
|
@@ -216,8 +214,7 @@ void IndexBinaryMultiHash::range_search(
|
|
|
216
214
|
int radius,
|
|
217
215
|
RangeSearchResult* result,
|
|
218
216
|
const SearchParameters* params) const {
|
|
219
|
-
|
|
220
|
-
!params, "search params not supported for this index");
|
|
217
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
221
218
|
size_t nlist = 0, ndis = 0, n0 = 0;
|
|
222
219
|
|
|
223
220
|
#pragma omp parallel if (n > 100) reduction(+ : ndis, n0, nlist)
|
|
@@ -249,8 +246,7 @@ void IndexBinaryMultiHash::search(
|
|
|
249
246
|
int32_t* distances,
|
|
250
247
|
idx_t* labels,
|
|
251
248
|
const SearchParameters* params) const {
|
|
252
|
-
|
|
253
|
-
!params, "search params not supported for this index");
|
|
249
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
254
250
|
FAISS_THROW_IF_NOT(k > 0);
|
|
255
251
|
|
|
256
252
|
using HeapForL2 = CMax<int32_t, idx_t>;
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
#include <faiss/impl/AuxIndexStructures.h>
|
|
23
23
|
#include <faiss/impl/FaissAssert.h>
|
|
24
24
|
#include <faiss/utils/hamming.h>
|
|
25
|
-
#include <faiss/utils/sorting.h>
|
|
26
25
|
#include <faiss/utils/utils.h>
|
|
27
26
|
|
|
28
27
|
#include <faiss/impl/simd_dispatch.h>
|
|
@@ -32,7 +31,6 @@
|
|
|
32
31
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
33
32
|
// NOLINTNEXTLINE(facebook-hte-InlineHeader)
|
|
34
33
|
#include <faiss/impl/binary_hamming/IndexBinaryIVF_impl.h>
|
|
35
|
-
#include <faiss/utils/hamming_distance/hamming_computer-generic.h>
|
|
36
34
|
#undef THE_SIMD_LEVEL
|
|
37
35
|
|
|
38
36
|
namespace faiss {
|
|
@@ -208,8 +206,7 @@ void IndexBinaryIVF::search_and_reconstruct(
|
|
|
208
206
|
idx_t* __restrict labels,
|
|
209
207
|
uint8_t* __restrict recons,
|
|
210
208
|
const SearchParameters* params) const {
|
|
211
|
-
|
|
212
|
-
!params, "search params not supported for this index");
|
|
209
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
213
210
|
const size_t nprobe_2 = std::min(nlist, this->nprobe);
|
|
214
211
|
FAISS_THROW_IF_NOT(k > 0);
|
|
215
212
|
FAISS_THROW_IF_NOT(nprobe_2 > 0);
|
|
@@ -257,7 +254,9 @@ void IndexBinaryIVF::reconstruct_from_offset(
|
|
|
257
254
|
idx_t list_no,
|
|
258
255
|
idx_t offset,
|
|
259
256
|
uint8_t* recons) const {
|
|
260
|
-
memcpy(recons,
|
|
257
|
+
memcpy(recons,
|
|
258
|
+
InvertedLists::ScopedCodes(invlists, list_no, offset).get(),
|
|
259
|
+
code_size);
|
|
261
260
|
}
|
|
262
261
|
|
|
263
262
|
void IndexBinaryIVF::reset() {
|
|
@@ -524,8 +523,7 @@ void IndexBinaryIVF::range_search(
|
|
|
524
523
|
int radius,
|
|
525
524
|
RangeSearchResult* __restrict res,
|
|
526
525
|
const SearchParameters* params) const {
|
|
527
|
-
|
|
528
|
-
!params, "search params not supported for this index");
|
|
526
|
+
FAISS_THROW_IF_MSG(params, "search params not supported for this index");
|
|
529
527
|
const size_t nprobe_2 = std::min(nlist, this->nprobe);
|
|
530
528
|
std::unique_ptr<idx_t[]> idx(new idx_t[n * nprobe_2]);
|
|
531
529
|
std::unique_ptr<int32_t[]> coarse_dis(new int32_t[n * nprobe_2]);
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include <faiss/IndexEDEN.h>
|
|
9
|
+
|
|
10
|
+
#include <faiss/impl/FaissAssert.h>
|
|
11
|
+
#include <faiss/impl/ResultHandler.h>
|
|
12
|
+
#include <memory>
|
|
13
|
+
|
|
14
|
+
namespace faiss {
|
|
15
|
+
|
|
16
|
+
IndexEDEN::IndexEDEN() = default;
|
|
17
|
+
|
|
18
|
+
IndexEDEN::IndexEDEN(
|
|
19
|
+
idx_t d_in,
|
|
20
|
+
MetricType metric,
|
|
21
|
+
uint8_t nb_bits_in,
|
|
22
|
+
EDENScaleType scale_type_in)
|
|
23
|
+
: IndexFlatCodes(0, d_in, metric),
|
|
24
|
+
sq(d_in, eden_utils::quantizer_type_for_bits(nb_bits_in)),
|
|
25
|
+
scale_type(scale_type_in) {
|
|
26
|
+
FAISS_THROW_IF_NOT_MSG(
|
|
27
|
+
scale_type == EDENScaleType_UNBIASED ||
|
|
28
|
+
scale_type == EDENScaleType_BIASED,
|
|
29
|
+
"invalid EDEN scale type");
|
|
30
|
+
sq.train(0, nullptr);
|
|
31
|
+
code_size = eden_utils::code_size(d, sq.bits);
|
|
32
|
+
is_trained = false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
void IndexEDEN::train(idx_t n, const float* x) {
|
|
36
|
+
std::vector<float> centroid(d, 0.0f);
|
|
37
|
+
for (idx_t i = 0; i < n; i++) {
|
|
38
|
+
for (size_t j = 0; j < static_cast<size_t>(d); j++) {
|
|
39
|
+
centroid[j] += x[i * d + j];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (n != 0) {
|
|
44
|
+
for (size_t j = 0; j < static_cast<size_t>(d); j++) {
|
|
45
|
+
centroid[j] /= static_cast<float>(n);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
center = std::move(centroid);
|
|
50
|
+
sq.train(n, x);
|
|
51
|
+
is_trained = true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void IndexEDEN::sa_encode(idx_t n, const float* x, uint8_t* bytes) const {
|
|
55
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
56
|
+
eden_utils::compute_codes(
|
|
57
|
+
sq, metric_type, scale_type, x, bytes, n, center.data());
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
void IndexEDEN::sa_decode(idx_t n, const uint8_t* bytes, float* x) const {
|
|
61
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
62
|
+
eden_utils::decode(sq, bytes, x, n, center.data());
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
FlatCodesDistanceComputer* IndexEDEN::get_FlatCodesDistanceComputer() const {
|
|
66
|
+
FlatCodesDistanceComputer* dc =
|
|
67
|
+
eden_utils::get_distance_computer(sq, metric_type, center.data());
|
|
68
|
+
dc->code_size = code_size;
|
|
69
|
+
dc->codes = codes.data();
|
|
70
|
+
return dc;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
namespace {
|
|
74
|
+
|
|
75
|
+
bool use_eden_batch_scan(size_t d, size_t nb_bits) {
|
|
76
|
+
const size_t values_per_byte = 8 / nb_bits;
|
|
77
|
+
const size_t num_bytes = (d + values_per_byte - 1) / values_per_byte;
|
|
78
|
+
if (nb_bits == 1) {
|
|
79
|
+
return num_bytes >= 32;
|
|
80
|
+
}
|
|
81
|
+
if (nb_bits == 2) {
|
|
82
|
+
return num_bytes >= 16;
|
|
83
|
+
}
|
|
84
|
+
if (nb_bits == 4) {
|
|
85
|
+
return num_bytes >= 128;
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
struct Run_search_with_eden_dc {
|
|
91
|
+
using T = void;
|
|
92
|
+
|
|
93
|
+
template <class BlockResultHandler>
|
|
94
|
+
void f(BlockResultHandler& res, const IndexEDEN* index, const float* xq) {
|
|
95
|
+
const size_t ntotal = index->ntotal;
|
|
96
|
+
using SingleResultHandler =
|
|
97
|
+
typename BlockResultHandler::SingleResultHandler;
|
|
98
|
+
const int d = index->d;
|
|
99
|
+
const bool use_batch_scan = use_eden_batch_scan(d, index->sq.bits);
|
|
100
|
+
|
|
101
|
+
#pragma omp parallel
|
|
102
|
+
{
|
|
103
|
+
std::unique_ptr<EDENFlatCodesDistanceComputer> dc(
|
|
104
|
+
eden_utils::get_distance_computer(
|
|
105
|
+
index->sq,
|
|
106
|
+
index->metric_type,
|
|
107
|
+
index->center.data()));
|
|
108
|
+
dc->code_size = index->code_size;
|
|
109
|
+
dc->codes = index->codes.data();
|
|
110
|
+
SingleResultHandler resi(res);
|
|
111
|
+
|
|
112
|
+
#pragma omp for
|
|
113
|
+
for (int64_t q = 0; q < static_cast<int64_t>(res.nq); q++) {
|
|
114
|
+
resi.begin(q);
|
|
115
|
+
dc->set_query(xq + d * q);
|
|
116
|
+
|
|
117
|
+
if (use_batch_scan) {
|
|
118
|
+
size_t i = 0;
|
|
119
|
+
for (; i + 16 <= ntotal; i += 16) {
|
|
120
|
+
bool keep[16];
|
|
121
|
+
bool keep_all = true;
|
|
122
|
+
for (size_t j = 0; j < 16; j++) {
|
|
123
|
+
keep[j] = res.is_in_selection(i + j);
|
|
124
|
+
keep_all &= keep[j];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (keep_all) {
|
|
128
|
+
float dis[16];
|
|
129
|
+
dc->consecutive_distances_batch_16(i, dis);
|
|
130
|
+
for (size_t j = 0; j < 16; j++) {
|
|
131
|
+
resi.add_result(dis[j], i + j);
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
for (size_t j = 0; j < 16; j++) {
|
|
135
|
+
if (keep[j]) {
|
|
136
|
+
resi.add_result((*dc)(i + j), i + j);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (; i + 8 <= ntotal; i += 8) {
|
|
142
|
+
const bool keep0 = res.is_in_selection(i);
|
|
143
|
+
const bool keep1 = res.is_in_selection(i + 1);
|
|
144
|
+
const bool keep2 = res.is_in_selection(i + 2);
|
|
145
|
+
const bool keep3 = res.is_in_selection(i + 3);
|
|
146
|
+
const bool keep4 = res.is_in_selection(i + 4);
|
|
147
|
+
const bool keep5 = res.is_in_selection(i + 5);
|
|
148
|
+
const bool keep6 = res.is_in_selection(i + 6);
|
|
149
|
+
const bool keep7 = res.is_in_selection(i + 7);
|
|
150
|
+
if (keep0 && keep1 && keep2 && keep3 && keep4 &&
|
|
151
|
+
keep5 && keep6 && keep7) {
|
|
152
|
+
float dis[8];
|
|
153
|
+
dc->consecutive_distances_batch_8(i, dis);
|
|
154
|
+
resi.add_result(dis[0], i);
|
|
155
|
+
resi.add_result(dis[1], i + 1);
|
|
156
|
+
resi.add_result(dis[2], i + 2);
|
|
157
|
+
resi.add_result(dis[3], i + 3);
|
|
158
|
+
resi.add_result(dis[4], i + 4);
|
|
159
|
+
resi.add_result(dis[5], i + 5);
|
|
160
|
+
resi.add_result(dis[6], i + 6);
|
|
161
|
+
resi.add_result(dis[7], i + 7);
|
|
162
|
+
} else {
|
|
163
|
+
if (keep0) {
|
|
164
|
+
resi.add_result((*dc)(i), i);
|
|
165
|
+
}
|
|
166
|
+
if (keep1) {
|
|
167
|
+
resi.add_result((*dc)(i + 1), i + 1);
|
|
168
|
+
}
|
|
169
|
+
if (keep2) {
|
|
170
|
+
resi.add_result((*dc)(i + 2), i + 2);
|
|
171
|
+
}
|
|
172
|
+
if (keep3) {
|
|
173
|
+
resi.add_result((*dc)(i + 3), i + 3);
|
|
174
|
+
}
|
|
175
|
+
if (keep4) {
|
|
176
|
+
resi.add_result((*dc)(i + 4), i + 4);
|
|
177
|
+
}
|
|
178
|
+
if (keep5) {
|
|
179
|
+
resi.add_result((*dc)(i + 5), i + 5);
|
|
180
|
+
}
|
|
181
|
+
if (keep6) {
|
|
182
|
+
resi.add_result((*dc)(i + 6), i + 6);
|
|
183
|
+
}
|
|
184
|
+
if (keep7) {
|
|
185
|
+
resi.add_result((*dc)(i + 7), i + 7);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
for (; i + 4 <= ntotal; i += 4) {
|
|
190
|
+
const bool keep0 = res.is_in_selection(i);
|
|
191
|
+
const bool keep1 = res.is_in_selection(i + 1);
|
|
192
|
+
const bool keep2 = res.is_in_selection(i + 2);
|
|
193
|
+
const bool keep3 = res.is_in_selection(i + 3);
|
|
194
|
+
if (keep0 && keep1 && keep2 && keep3) {
|
|
195
|
+
float dis0;
|
|
196
|
+
float dis1;
|
|
197
|
+
float dis2;
|
|
198
|
+
float dis3;
|
|
199
|
+
dc->distances_batch_4(
|
|
200
|
+
i,
|
|
201
|
+
i + 1,
|
|
202
|
+
i + 2,
|
|
203
|
+
i + 3,
|
|
204
|
+
dis0,
|
|
205
|
+
dis1,
|
|
206
|
+
dis2,
|
|
207
|
+
dis3);
|
|
208
|
+
resi.add_result(dis0, i);
|
|
209
|
+
resi.add_result(dis1, i + 1);
|
|
210
|
+
resi.add_result(dis2, i + 2);
|
|
211
|
+
resi.add_result(dis3, i + 3);
|
|
212
|
+
} else {
|
|
213
|
+
if (keep0) {
|
|
214
|
+
resi.add_result((*dc)(i), i);
|
|
215
|
+
}
|
|
216
|
+
if (keep1) {
|
|
217
|
+
resi.add_result((*dc)(i + 1), i + 1);
|
|
218
|
+
}
|
|
219
|
+
if (keep2) {
|
|
220
|
+
resi.add_result((*dc)(i + 2), i + 2);
|
|
221
|
+
}
|
|
222
|
+
if (keep3) {
|
|
223
|
+
resi.add_result((*dc)(i + 3), i + 3);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
for (; i < ntotal; i++) {
|
|
228
|
+
if (res.is_in_selection(i)) {
|
|
229
|
+
resi.add_result((*dc)(i), i);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
for (size_t i = 0; i < ntotal; i++) {
|
|
234
|
+
if (res.is_in_selection(i)) {
|
|
235
|
+
resi.add_result((*dc)(i), i);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
resi.end();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
} // namespace
|
|
247
|
+
|
|
248
|
+
void IndexEDEN::search(
|
|
249
|
+
idx_t n,
|
|
250
|
+
const float* x,
|
|
251
|
+
idx_t k,
|
|
252
|
+
float* distances,
|
|
253
|
+
idx_t* labels,
|
|
254
|
+
const SearchParameters* params) const {
|
|
255
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
256
|
+
const IDSelector* sel = params != nullptr ? params->sel : nullptr;
|
|
257
|
+
Run_search_with_eden_dc r;
|
|
258
|
+
dispatch_knn_ResultHandler(
|
|
259
|
+
n, distances, labels, k, metric_type, sel, r, this, x);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
void IndexEDEN::range_search(
|
|
263
|
+
idx_t /*n*/,
|
|
264
|
+
const float* x,
|
|
265
|
+
float radius,
|
|
266
|
+
RangeSearchResult* result,
|
|
267
|
+
const SearchParameters* params) const {
|
|
268
|
+
const IDSelector* sel = params != nullptr ? params->sel : nullptr;
|
|
269
|
+
Run_search_with_eden_dc r;
|
|
270
|
+
dispatch_range_ResultHandler(result, radius, metric_type, sel, r, this, x);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
} // namespace faiss
|