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
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
#include <faiss/IndexBinaryFlat.h>
|
|
15
15
|
#include <faiss/IndexBinaryHNSW.h>
|
|
16
16
|
#include <faiss/IndexBinaryIVF.h>
|
|
17
|
+
#include <faiss/IndexEDEN.h>
|
|
17
18
|
#include <faiss/IndexHNSW.h>
|
|
18
19
|
#include <faiss/IndexIDMap.h>
|
|
20
|
+
#include <faiss/IndexIVFEDEN.h>
|
|
19
21
|
#include <faiss/IndexIVFFlat.h>
|
|
20
22
|
#include <faiss/IndexIVFPQFastScan.h>
|
|
21
23
|
#include <faiss/IndexIVFRaBitQ.h>
|
|
@@ -33,16 +35,26 @@ namespace {
|
|
|
33
35
|
const std::map<faiss::ScalarQuantizer::QuantizerType, std::string> sq_types = {
|
|
34
36
|
{faiss::ScalarQuantizer::QT_8bit, "SQ8"},
|
|
35
37
|
{faiss::ScalarQuantizer::QT_4bit, "SQ4"},
|
|
38
|
+
// QT_8bit_uniform and QT_4bit_uniform have no round-trippable
|
|
39
|
+
// index_factory string; the names below are synthetic identifiers used
|
|
40
|
+
// for telemetry logging only.
|
|
41
|
+
{faiss::ScalarQuantizer::QT_8bit_uniform, "SQ8u"},
|
|
42
|
+
{faiss::ScalarQuantizer::QT_4bit_uniform, "SQ4u"},
|
|
36
43
|
{faiss::ScalarQuantizer::QT_6bit, "SQ6"},
|
|
37
44
|
{faiss::ScalarQuantizer::QT_fp16, "SQfp16"},
|
|
38
45
|
{faiss::ScalarQuantizer::QT_bf16, "SQbf16"},
|
|
39
46
|
{faiss::ScalarQuantizer::QT_8bit_direct_signed, "SQ8_direct_signed"},
|
|
40
47
|
{faiss::ScalarQuantizer::QT_8bit_direct, "SQ8_direct"},
|
|
48
|
+
{faiss::ScalarQuantizer::QT_0bit, "SQ0"},
|
|
41
49
|
{faiss::ScalarQuantizer::QT_1bit_tqmse, "SQtqmse1"},
|
|
42
50
|
{faiss::ScalarQuantizer::QT_2bit_tqmse, "SQtqmse2"},
|
|
43
51
|
{faiss::ScalarQuantizer::QT_3bit_tqmse, "SQtqmse3"},
|
|
44
52
|
{faiss::ScalarQuantizer::QT_4bit_tqmse, "SQtqmse4"},
|
|
45
53
|
{faiss::ScalarQuantizer::QT_8bit_tqmse, "SQtqmse8"},
|
|
54
|
+
{faiss::ScalarQuantizer::QT_2bit_tq, "SQtq2"},
|
|
55
|
+
{faiss::ScalarQuantizer::QT_3bit_tq, "SQtq3"},
|
|
56
|
+
{faiss::ScalarQuantizer::QT_4bit_tq, "SQtq4"},
|
|
57
|
+
{faiss::ScalarQuantizer::QT_5bit_tq, "SQtq5"},
|
|
46
58
|
};
|
|
47
59
|
|
|
48
60
|
int get_hnsw_M(const faiss::IndexHNSW* index) {
|
|
@@ -61,6 +73,19 @@ int get_hnsw_M(const faiss::IndexBinaryHNSW* index) {
|
|
|
61
73
|
return 0;
|
|
62
74
|
}
|
|
63
75
|
|
|
76
|
+
std::string eden_factory_string(
|
|
77
|
+
const faiss::ScalarQuantizer& sq,
|
|
78
|
+
faiss::EDENScaleType scale_type) {
|
|
79
|
+
std::string result = "EDEN";
|
|
80
|
+
if (sq.bits != 1) {
|
|
81
|
+
result += std::to_string(sq.bits);
|
|
82
|
+
}
|
|
83
|
+
if (scale_type == faiss::EDENScaleType_BIASED) {
|
|
84
|
+
result += "BIASED";
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
|
|
64
89
|
} // namespace
|
|
65
90
|
|
|
66
91
|
// Reference for reverse_index_factory:
|
|
@@ -110,8 +135,17 @@ std::string reverse_index_factory(const faiss::Index* index) {
|
|
|
110
135
|
ivf_index)) {
|
|
111
136
|
return prefix + ",PQ" + std::to_string(ivfpqfs_index->pq.M) + "x" +
|
|
112
137
|
std::to_string(ivfpqfs_index->pq.nbits) + "fs";
|
|
113
|
-
} else if (
|
|
114
|
-
|
|
138
|
+
} else if (
|
|
139
|
+
const faiss::IndexIVFRaBitQ* ivfrabitq_index =
|
|
140
|
+
dynamic_cast<const faiss::IndexIVFRaBitQ*>(ivf_index)) {
|
|
141
|
+
size_t nb_bits = ivfrabitq_index->rabitq.nb_bits;
|
|
142
|
+
return prefix + ",RaBitQ" +
|
|
143
|
+
(nb_bits == 1 ? "" : std::to_string(nb_bits));
|
|
144
|
+
} else if (
|
|
145
|
+
const faiss::IndexIVFEDEN* ivf_eden =
|
|
146
|
+
dynamic_cast<const faiss::IndexIVFEDEN*>(ivf_index)) {
|
|
147
|
+
return prefix + "," +
|
|
148
|
+
eden_factory_string(ivf_eden->sq, ivf_eden->scale_type);
|
|
115
149
|
}
|
|
116
150
|
} else if (
|
|
117
151
|
const faiss::IndexPreTransform* pretransform_index =
|
|
@@ -180,12 +214,25 @@ std::string reverse_index_factory(const faiss::Index* index) {
|
|
|
180
214
|
const faiss::IndexScalarQuantizer* sq_index =
|
|
181
215
|
dynamic_cast<const faiss::IndexScalarQuantizer*>(index)) {
|
|
182
216
|
return sq_types.at(sq_index->sq.qtype);
|
|
217
|
+
} else if (
|
|
218
|
+
// IndexIDMap2 inherits IndexIDMap — check subclass first.
|
|
219
|
+
const faiss::IndexIDMap2* idmap2 =
|
|
220
|
+
dynamic_cast<const faiss::IndexIDMap2*>(index)) {
|
|
221
|
+
return std::string("IDMap2,") + reverse_index_factory(idmap2->index);
|
|
183
222
|
} else if (
|
|
184
223
|
const faiss::IndexIDMap* idmap =
|
|
185
224
|
dynamic_cast<const faiss::IndexIDMap*>(index)) {
|
|
186
225
|
return std::string("IDMap,") + reverse_index_factory(idmap->index);
|
|
187
|
-
} else if (
|
|
188
|
-
|
|
226
|
+
} else if (
|
|
227
|
+
const faiss::IndexRaBitQ* rabitq_index =
|
|
228
|
+
dynamic_cast<const faiss::IndexRaBitQ*>(index)) {
|
|
229
|
+
size_t nb_bits = rabitq_index->rabitq.nb_bits;
|
|
230
|
+
return "RaBitQ" +
|
|
231
|
+
(nb_bits == 1 ? std::string() : std::to_string(nb_bits));
|
|
232
|
+
} else if (
|
|
233
|
+
const faiss::IndexEDEN* eden =
|
|
234
|
+
dynamic_cast<const faiss::IndexEDEN*>(index)) {
|
|
235
|
+
return eden_factory_string(eden->sq, eden->scale_type);
|
|
189
236
|
}
|
|
190
237
|
// Avoid runtime error, just return empty string for logging.
|
|
191
238
|
return "";
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
#include <faiss/IndexBinaryFlat.h>
|
|
16
16
|
#include <faiss/IndexFlat.h>
|
|
17
|
-
#if defined
|
|
17
|
+
#if defined(USE_NVIDIA_CUVS) && !defined(FAISS_CUVS_NO_CAGRA)
|
|
18
18
|
#include <faiss/IndexBinaryHNSW.h>
|
|
19
19
|
#include <faiss/IndexHNSW.h>
|
|
20
20
|
#endif
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
#include <faiss/MetaIndexes.h>
|
|
29
29
|
#include <faiss/gpu/GpuIndex.h>
|
|
30
30
|
#include <faiss/gpu/GpuIndexBinaryFlat.h>
|
|
31
|
-
#if defined
|
|
31
|
+
#if defined(USE_NVIDIA_CUVS) && !defined(FAISS_CUVS_NO_CAGRA)
|
|
32
32
|
#include <faiss/gpu/GpuIndexBinaryCagra.h>
|
|
33
33
|
#include <faiss/gpu/GpuIndexCagra.h>
|
|
34
34
|
#endif
|
|
@@ -92,7 +92,7 @@ Index* ToCPUCloner::clone_Index(const Index* index) {
|
|
|
92
92
|
// (inverse op of ToGpuClonerMultiple)
|
|
93
93
|
|
|
94
94
|
}
|
|
95
|
-
#if defined
|
|
95
|
+
#if defined(USE_NVIDIA_CUVS) && !defined(FAISS_CUVS_NO_CAGRA)
|
|
96
96
|
else if (auto icg = dynamic_cast<const GpuIndexCagra*>(index)) {
|
|
97
97
|
IndexHNSWCagra* res = new IndexHNSWCagra();
|
|
98
98
|
if (icg->get_numeric_type() != faiss::NumericType::Float32) {
|
|
@@ -150,8 +150,8 @@ Index* ToGpuCloner::clone_Index(const Index* index) {
|
|
|
150
150
|
GpuIndexFlatConfig config;
|
|
151
151
|
config.device = device;
|
|
152
152
|
config.useFloat16 = true;
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
FAISS_THROW_IF_MSG(
|
|
154
|
+
use_cuvs, "this type of index is not implemented for cuVS");
|
|
155
155
|
GpuIndexFlat* gif = new GpuIndexFlat(
|
|
156
156
|
provider, index->d, index->metric_type, config);
|
|
157
157
|
// transfer data by blocks
|
|
@@ -187,8 +187,8 @@ Index* ToGpuCloner::clone_Index(const Index* index) {
|
|
|
187
187
|
config.device = device;
|
|
188
188
|
config.indicesOptions = indicesOptions;
|
|
189
189
|
config.flatConfig.useFloat16 = useFloat16CoarseQuantizer;
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
config.use_cuvs = use_cuvs;
|
|
191
|
+
config.allowCpuCoarseQuantizer = allowCpuCoarseQuantizer;
|
|
192
192
|
|
|
193
193
|
GpuIndexIVFScalarQuantizer* res = new GpuIndexIVFScalarQuantizer(
|
|
194
194
|
provider,
|
|
@@ -233,7 +233,7 @@ Index* ToGpuCloner::clone_Index(const Index* index) {
|
|
|
233
233
|
|
|
234
234
|
return res;
|
|
235
235
|
}
|
|
236
|
-
#if defined
|
|
236
|
+
#if defined(USE_NVIDIA_CUVS) && !defined(FAISS_CUVS_NO_CAGRA)
|
|
237
237
|
else if (auto icg = dynamic_cast<const faiss::IndexHNSWCagra*>(index)) {
|
|
238
238
|
GpuIndexCagraConfig config;
|
|
239
239
|
config.device = device;
|
|
@@ -533,7 +533,7 @@ faiss::IndexBinary* index_binary_gpu_to_cpu(
|
|
|
533
533
|
ii->copyTo(ret);
|
|
534
534
|
return ret;
|
|
535
535
|
}
|
|
536
|
-
#if defined
|
|
536
|
+
#if defined(USE_NVIDIA_CUVS) && !defined(FAISS_CUVS_NO_CAGRA)
|
|
537
537
|
else if (auto ii = dynamic_cast<const GpuIndexBinaryCagra*>(gpu_index)) {
|
|
538
538
|
IndexBinaryHNSWCagra* ret = new IndexBinaryHNSWCagra();
|
|
539
539
|
ii->copyTo(ret);
|
|
@@ -549,13 +549,13 @@ faiss::IndexBinary* index_binary_cpu_to_gpu(
|
|
|
549
549
|
GpuResourcesProvider* provider,
|
|
550
550
|
int device,
|
|
551
551
|
const faiss::IndexBinary* index,
|
|
552
|
-
const GpuClonerOptions* options) {
|
|
552
|
+
const GpuClonerOptions* /*options*/) {
|
|
553
553
|
if (auto ii = dynamic_cast<const IndexBinaryFlat*>(index)) {
|
|
554
554
|
GpuIndexBinaryFlatConfig config;
|
|
555
555
|
config.device = device;
|
|
556
556
|
return new GpuIndexBinaryFlat(provider, ii, config);
|
|
557
557
|
}
|
|
558
|
-
#if defined
|
|
558
|
+
#if defined(USE_NVIDIA_CUVS) && !defined(FAISS_CUVS_NO_CAGRA)
|
|
559
559
|
else if (
|
|
560
560
|
auto ii = dynamic_cast<const faiss::IndexBinaryHNSWCagra*>(index)) {
|
|
561
561
|
GpuIndexCagraConfig config;
|
|
@@ -177,6 +177,33 @@ class GpuIndex : public faiss::Index {
|
|
|
177
177
|
}
|
|
178
178
|
};
|
|
179
179
|
|
|
180
|
+
virtual void addImplPrecomputed_(
|
|
181
|
+
idx_t n,
|
|
182
|
+
const float* x,
|
|
183
|
+
const idx_t* ids,
|
|
184
|
+
const idx_t* precomputed_idx);
|
|
185
|
+
|
|
186
|
+
virtual void addImplPrecomputed_ex_(
|
|
187
|
+
idx_t n,
|
|
188
|
+
const void* x,
|
|
189
|
+
NumericType numeric_type,
|
|
190
|
+
const idx_t* ids,
|
|
191
|
+
const idx_t* precomputed_idx);
|
|
192
|
+
|
|
193
|
+
/// Handles paged adds if the add set is too large, passes to
|
|
194
|
+
/// addImpl_ to actually perform the add for the current page
|
|
195
|
+
void addPaged_(
|
|
196
|
+
idx_t n,
|
|
197
|
+
const float* x,
|
|
198
|
+
const idx_t* ids,
|
|
199
|
+
const idx_t* precomputed_idx = nullptr);
|
|
200
|
+
void addPaged_ex_(
|
|
201
|
+
idx_t n,
|
|
202
|
+
const void* x,
|
|
203
|
+
NumericType numeric_type,
|
|
204
|
+
const idx_t* ids,
|
|
205
|
+
const idx_t* precomputed_idx = nullptr);
|
|
206
|
+
|
|
180
207
|
/// Overridden to actually perform the search
|
|
181
208
|
/// All data is guaranteed to be resident on our device
|
|
182
209
|
virtual void searchImpl_(
|
|
@@ -209,22 +236,18 @@ class GpuIndex : public faiss::Index {
|
|
|
209
236
|
}
|
|
210
237
|
|
|
211
238
|
private:
|
|
212
|
-
/// Handles paged adds if the add set is too large, passes to
|
|
213
|
-
/// addImpl_ to actually perform the add for the current page
|
|
214
|
-
void addPaged_(idx_t n, const float* x, const idx_t* ids);
|
|
215
|
-
void addPaged_ex_(
|
|
216
|
-
idx_t n,
|
|
217
|
-
const void* x,
|
|
218
|
-
NumericType numeric_type,
|
|
219
|
-
const idx_t* ids);
|
|
220
|
-
|
|
221
239
|
/// Calls addImpl_ for a single page of GPU-resident data
|
|
222
|
-
void addPage_(
|
|
240
|
+
void addPage_(
|
|
241
|
+
idx_t n,
|
|
242
|
+
const float* x,
|
|
243
|
+
const idx_t* ids,
|
|
244
|
+
const idx_t* precomputed_idx = nullptr);
|
|
223
245
|
void addPage_ex_(
|
|
224
246
|
idx_t n,
|
|
225
247
|
const void* x,
|
|
226
248
|
NumericType numeric_type,
|
|
227
|
-
const idx_t* ids
|
|
249
|
+
const idx_t* ids,
|
|
250
|
+
const idx_t* precomputed_idx = nullptr);
|
|
228
251
|
|
|
229
252
|
/// Calls searchImpl_ for a single page of GPU-resident data
|
|
230
253
|
void searchNonPaged_(
|
|
@@ -284,6 +284,46 @@ struct GpuIndexCagra : public GpuIndex {
|
|
|
284
284
|
/// in the index instance
|
|
285
285
|
void copyTo(faiss::IndexHNSWCagra* index) const;
|
|
286
286
|
|
|
287
|
+
/// Train CAGRA using multiple GPUs by sharding the dataset.
|
|
288
|
+
/// Uses cuVS native SNMG (single-node multi-GPU) CAGRA build.
|
|
289
|
+
/// Each device builds one shard in parallel via OpenMP.
|
|
290
|
+
/// Float32 only. After training, call copyTo() to produce a CPU
|
|
291
|
+
/// IndexHNSWCagra with full HNSW upper levels.
|
|
292
|
+
/// The training data pointer must remain valid until copyTo() completes.
|
|
293
|
+
/// stitch_mode: 0=CPU HNSW (Approach C), 1=GPU brute-force (Approach B)
|
|
294
|
+
void trainMultiGpu(
|
|
295
|
+
idx_t n,
|
|
296
|
+
const float* x,
|
|
297
|
+
std::vector<GpuResourcesProvider*>& providers,
|
|
298
|
+
std::vector<int>& devices,
|
|
299
|
+
idx_t stitch_per_shard = 0,
|
|
300
|
+
int stitch_k = 2,
|
|
301
|
+
int stitch_mode = 0);
|
|
302
|
+
|
|
303
|
+
/// Build a unified CAGRA graph using cuVS all_neighbors
|
|
304
|
+
/// (multi-GPU kNN graph construction with overlapping clusters) followed
|
|
305
|
+
/// by cagra::optimize (graph pruning). Produces a single unified graph
|
|
306
|
+
/// without stitching. The training data pointer must remain valid until
|
|
307
|
+
/// copyTo() completes.
|
|
308
|
+
/// build_algo: 0=NN-descent (default), 1=brute-force, 2=IVF-PQ
|
|
309
|
+
/// refinement_rate: IVF-PQ refinement multiplier (only used when
|
|
310
|
+
/// build_algo==2). Higher values trade build time for recall; the cuVS
|
|
311
|
+
/// default is 2.0.
|
|
312
|
+
/// ivfpq_search_batch: cap the IVF-PQ search `max_internal_batch_size` used
|
|
313
|
+
/// during the all_neighbors kNN build (build_algo==2). 0 = cuVS default
|
|
314
|
+
/// (128*1024), which can OOM at 100M; a smaller value (e.g. 8192) bounds
|
|
315
|
+
/// the GPU search workspace with no effect on results (recall-neutral).
|
|
316
|
+
void trainAllNeighbors(
|
|
317
|
+
idx_t n,
|
|
318
|
+
const float* x,
|
|
319
|
+
std::vector<int>& devices,
|
|
320
|
+
int n_clusters = 0,
|
|
321
|
+
int overlap_factor = 0,
|
|
322
|
+
bool multi_gpu_optimize = false,
|
|
323
|
+
int build_algo = 0,
|
|
324
|
+
float refinement_rate = 2.0f,
|
|
325
|
+
int ivfpq_search_batch = 0);
|
|
326
|
+
|
|
287
327
|
void reset() override;
|
|
288
328
|
|
|
289
329
|
std::vector<idx_t> get_knngraph() const;
|
|
@@ -317,6 +357,8 @@ struct GpuIndexCagra : public GpuIndex {
|
|
|
317
357
|
idx_t* labels,
|
|
318
358
|
const SearchParameters* search_params) const override;
|
|
319
359
|
|
|
360
|
+
void copyToMultiGpu_(faiss::IndexHNSWCagra* index) const;
|
|
361
|
+
|
|
320
362
|
/// Our configuration options
|
|
321
363
|
const GpuIndexCagraConfig cagraConfig_;
|
|
322
364
|
|
|
@@ -329,6 +371,11 @@ struct GpuIndexCagra : public GpuIndex {
|
|
|
329
371
|
std::shared_ptr<CuvsCagra<half>>,
|
|
330
372
|
std::shared_ptr<CuvsCagra<int8_t>>>
|
|
331
373
|
index_;
|
|
374
|
+
|
|
375
|
+
/// Multi-GPU state: populated by trainMultiGpu(), used by copyTo()
|
|
376
|
+
std::vector<idx_t> merged_knngraph_;
|
|
377
|
+
idx_t merged_knngraph_degree_ = 0;
|
|
378
|
+
const float* multi_gpu_dataset_ = nullptr;
|
|
332
379
|
};
|
|
333
380
|
|
|
334
381
|
} // namespace gpu
|
|
@@ -98,6 +98,17 @@ class GpuIndexIVF : public GpuIndex, public IndexIVFInterface {
|
|
|
98
98
|
/// debugging purposes.
|
|
99
99
|
virtual std::vector<idx_t> getListIndices(idx_t listId) const;
|
|
100
100
|
|
|
101
|
+
/// Add vectors with precomputed IVF list assignments.
|
|
102
|
+
/// Same naming and argument order as IndexIVF::add_core.
|
|
103
|
+
/// `x`, `xids`, and `precomputed_idx` can be resident on the CPU or any
|
|
104
|
+
/// GPU; copies are performed as needed.
|
|
105
|
+
void add_core(
|
|
106
|
+
idx_t n,
|
|
107
|
+
const float* x,
|
|
108
|
+
const idx_t* xids,
|
|
109
|
+
const idx_t* precomputed_idx,
|
|
110
|
+
void* inverted_list_context = nullptr);
|
|
111
|
+
|
|
101
112
|
void search_preassigned(
|
|
102
113
|
idx_t n,
|
|
103
114
|
const float* x,
|
|
@@ -133,6 +144,12 @@ class GpuIndexIVF : public GpuIndex, public IndexIVFInterface {
|
|
|
133
144
|
/// Called from GpuIndex for add/add_with_ids
|
|
134
145
|
void addImpl_(idx_t n, const float* x, const idx_t* ids) override;
|
|
135
146
|
|
|
147
|
+
void addImplPrecomputed_(
|
|
148
|
+
idx_t n,
|
|
149
|
+
const float* x,
|
|
150
|
+
const idx_t* xids,
|
|
151
|
+
const idx_t* precomputed_idx) override;
|
|
152
|
+
|
|
136
153
|
/// Called from GpuIndex for search
|
|
137
154
|
void searchImpl_(
|
|
138
155
|
idx_t n,
|
|
@@ -93,6 +93,22 @@ class GpuIndexIVFScalarQuantizer : public GpuIndexIVF {
|
|
|
93
93
|
/// Validates index SQ parameters
|
|
94
94
|
void verifySQSettings_() const;
|
|
95
95
|
|
|
96
|
+
/// Whether this index configuration can use cuVS IVF-SQ
|
|
97
|
+
bool shouldUseCuvs_() const;
|
|
98
|
+
|
|
99
|
+
/// Construct the backing IVF implementation
|
|
100
|
+
void setIndex_(
|
|
101
|
+
GpuResources* resources,
|
|
102
|
+
int dim,
|
|
103
|
+
idx_t nlist,
|
|
104
|
+
faiss::MetricType metric,
|
|
105
|
+
float metricArg,
|
|
106
|
+
bool useResidual,
|
|
107
|
+
faiss::ScalarQuantizer* scalarQ,
|
|
108
|
+
bool interleavedLayout,
|
|
109
|
+
IndicesOptions indicesOptions,
|
|
110
|
+
MemorySpace space);
|
|
111
|
+
|
|
96
112
|
/// Called from train to handle SQ residual training
|
|
97
113
|
void trainResiduals_(idx_t n, const float* x);
|
|
98
114
|
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
|
|
34
34
|
#if defined USE_NVIDIA_CUVS
|
|
35
35
|
#include <raft/core/device_resources.hpp>
|
|
36
|
-
#include <
|
|
36
|
+
#include <cuda/memory_resource>
|
|
37
|
+
#include <optional>
|
|
37
38
|
#endif
|
|
38
39
|
|
|
39
40
|
namespace faiss {
|
|
@@ -163,7 +164,7 @@ struct AllocRequest : public AllocInfo {
|
|
|
163
164
|
size_t size = 0;
|
|
164
165
|
|
|
165
166
|
#if defined USE_NVIDIA_CUVS
|
|
166
|
-
|
|
167
|
+
std::optional<cuda::mr::any_resource<cuda::mr::device_accessible>> mr;
|
|
167
168
|
#endif
|
|
168
169
|
};
|
|
169
170
|
|
|
@@ -92,8 +92,8 @@ std::string allocsToString(const std::unordered_map<void*, AllocRequest>& map) {
|
|
|
92
92
|
StandardGpuResourcesImpl::StandardGpuResourcesImpl()
|
|
93
93
|
:
|
|
94
94
|
#if defined USE_NVIDIA_CUVS
|
|
95
|
-
mmr_
|
|
96
|
-
pmr_
|
|
95
|
+
mmr_{},
|
|
96
|
+
pmr_{},
|
|
97
97
|
#endif
|
|
98
98
|
pinnedMemAlloc_(nullptr),
|
|
99
99
|
pinnedMemAllocSize_(0),
|
|
@@ -164,7 +164,7 @@ StandardGpuResourcesImpl::~StandardGpuResourcesImpl() {
|
|
|
164
164
|
|
|
165
165
|
if (pinnedMemAlloc_) {
|
|
166
166
|
#if defined USE_NVIDIA_CUVS
|
|
167
|
-
pmr_
|
|
167
|
+
pmr_.deallocate_sync(pinnedMemAlloc_, pinnedMemAllocSize_);
|
|
168
168
|
#else
|
|
169
169
|
auto err = cudaFreeHost(pinnedMemAlloc_);
|
|
170
170
|
FAISS_ASSERT_FMT(
|
|
@@ -350,7 +350,7 @@ void StandardGpuResourcesImpl::initializeForDevice(int device) {
|
|
|
350
350
|
// pinned memory allocation
|
|
351
351
|
if (defaultStreams_.empty() && pinnedMemSize_ > 0) {
|
|
352
352
|
try {
|
|
353
|
-
pinnedMemAlloc_ = pmr_
|
|
353
|
+
pinnedMemAlloc_ = pmr_.allocate_sync(pinnedMemSize_);
|
|
354
354
|
} catch (const std::bad_alloc& rmm_ex) {
|
|
355
355
|
FAISS_THROW_MSG("CUDA memory allocation error");
|
|
356
356
|
}
|
|
@@ -546,10 +546,9 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) {
|
|
|
546
546
|
} else if (adjReq.space == MemorySpace::Device) {
|
|
547
547
|
#if defined USE_NVIDIA_CUVS
|
|
548
548
|
try {
|
|
549
|
-
rmm::mr::
|
|
550
|
-
rmm::
|
|
551
|
-
|
|
552
|
-
p = current_mr->allocate(adjReq.stream, adjReq.size);
|
|
549
|
+
auto current_mr = rmm::mr::get_per_device_resource_ref(
|
|
550
|
+
rmm::cuda_device_id{adjReq.device});
|
|
551
|
+
p = current_mr.allocate(adjReq.stream, adjReq.size);
|
|
553
552
|
adjReq.mr = current_mr;
|
|
554
553
|
} catch (const std::bad_alloc& rmm_ex) {
|
|
555
554
|
FAISS_THROW_MSG("CUDA memory allocation error");
|
|
@@ -562,7 +561,7 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) {
|
|
|
562
561
|
// FIXME: as of CUDA 11, a memory allocation error appears to be
|
|
563
562
|
// presented via cudaGetLastError as well, and needs to be
|
|
564
563
|
// cleared. Just call the function to clear it
|
|
565
|
-
cudaGetLastError();
|
|
564
|
+
(void)cudaGetLastError();
|
|
566
565
|
|
|
567
566
|
std::stringstream ss;
|
|
568
567
|
ss << "StandardGpuResources: alloc fail " << adjReq.toString()
|
|
@@ -584,8 +583,8 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) {
|
|
|
584
583
|
// TODO: change this to use the current device resource once RMM has
|
|
585
584
|
// a way to retrieve a "guaranteed" managed memory resource for a
|
|
586
585
|
// device.
|
|
587
|
-
p = mmr_
|
|
588
|
-
adjReq.mr = mmr_
|
|
586
|
+
p = mmr_.allocate(adjReq.stream, adjReq.size);
|
|
587
|
+
adjReq.mr = mmr_;
|
|
589
588
|
} catch (const std::bad_alloc& rmm_ex) {
|
|
590
589
|
FAISS_THROW_MSG("CUDA memory allocation error");
|
|
591
590
|
}
|
|
@@ -596,7 +595,7 @@ void* StandardGpuResourcesImpl::allocMemory(const AllocRequest& req) {
|
|
|
596
595
|
// FIXME: as of CUDA 11, a memory allocation error appears to be
|
|
597
596
|
// presented via cudaGetLastError as well, and needs to be cleared.
|
|
598
597
|
// Just call the function to clear it
|
|
599
|
-
cudaGetLastError();
|
|
598
|
+
(void)cudaGetLastError();
|
|
600
599
|
|
|
601
600
|
std::stringstream ss;
|
|
602
601
|
ss << "StandardGpuResources: alloc fail " << adjReq.toString()
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
#if defined USE_NVIDIA_CUVS
|
|
27
27
|
#include <raft/core/device_resources.hpp>
|
|
28
|
-
#include <rmm/mr/
|
|
28
|
+
#include <rmm/mr/managed_memory_resource.hpp>
|
|
29
29
|
#include <rmm/mr/pinned_host_memory_resource.hpp>
|
|
30
30
|
#endif
|
|
31
31
|
|
|
@@ -171,10 +171,10 @@ class StandardGpuResourcesImpl : public GpuResources {
|
|
|
171
171
|
*/
|
|
172
172
|
|
|
173
173
|
// managed_memory_resource
|
|
174
|
-
|
|
174
|
+
rmm::mr::managed_memory_resource mmr_;
|
|
175
175
|
|
|
176
176
|
// pinned_host_memory_resource
|
|
177
|
-
|
|
177
|
+
rmm::mr::pinned_host_memory_resource pmr_;
|
|
178
178
|
#endif
|
|
179
179
|
|
|
180
180
|
/// Pinned memory allocation for use with this GPU
|
|
@@ -42,7 +42,7 @@ using namespace faiss::gpu;
|
|
|
42
42
|
int main(int argc, char** argv) {
|
|
43
43
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
|
44
44
|
|
|
45
|
-
cudaProfilerStop();
|
|
45
|
+
CUDA_VERIFY(cudaProfilerStop());
|
|
46
46
|
|
|
47
47
|
auto seed = FLAGS_seed != -1 ? FLAGS_seed : time(nullptr);
|
|
48
48
|
printf("using seed %ld\n", seed);
|
|
@@ -31,7 +31,7 @@ DEFINE_bool(reserve_memory, false, "whether or not to pre-reserve memory");
|
|
|
31
31
|
int main(int argc, char** argv) {
|
|
32
32
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
|
33
33
|
|
|
34
|
-
cudaProfilerStop();
|
|
34
|
+
CUDA_VERIFY(cudaProfilerStop());
|
|
35
35
|
|
|
36
36
|
int dim = FLAGS_dim;
|
|
37
37
|
int numCentroids = FLAGS_centroids;
|
|
@@ -72,7 +72,7 @@ int main(int argc, char** argv) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
cudaDeviceSynchronize();
|
|
75
|
+
CUDA_VERIFY(cudaDeviceSynchronize());
|
|
76
76
|
CUDA_VERIFY(cudaProfilerStart());
|
|
77
77
|
|
|
78
78
|
float totalGpuTime = 0.0f;
|