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
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @lint-ignore-every LICENSELINT
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* C++-only API for Python/SWIG. No Objective-C types so SWIG can
|
|
9
|
+
* parse it. Implemented in MetalPythonBridge.mm.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
#pragma once
|
|
13
|
+
|
|
14
|
+
#include <faiss/Index.h>
|
|
15
|
+
|
|
16
|
+
namespace faiss {
|
|
17
|
+
namespace gpu_metal {
|
|
18
|
+
|
|
19
|
+
/// Opaque holder for Metal resources.
|
|
20
|
+
struct StandardMetalResourcesHolder {
|
|
21
|
+
void* impl = nullptr;
|
|
22
|
+
StandardMetalResourcesHolder();
|
|
23
|
+
~StandardMetalResourcesHolder();
|
|
24
|
+
StandardMetalResourcesHolder(const StandardMetalResourcesHolder&) = delete;
|
|
25
|
+
StandardMetalResourcesHolder& operator=(
|
|
26
|
+
const StandardMetalResourcesHolder&) = delete;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/// Same names as GPU API for unified Python binding.
|
|
30
|
+
int get_num_gpus();
|
|
31
|
+
void gpu_profiler_start();
|
|
32
|
+
void gpu_profiler_stop();
|
|
33
|
+
void gpu_sync_all_devices();
|
|
34
|
+
|
|
35
|
+
/// Clone CPU index to Metal GPU. Caller owns returned index.
|
|
36
|
+
faiss::Index* index_cpu_to_gpu(
|
|
37
|
+
StandardMetalResourcesHolder* res,
|
|
38
|
+
int device,
|
|
39
|
+
const faiss::Index* index);
|
|
40
|
+
|
|
41
|
+
/// Copy Metal index back to CPU. Caller owns returned index.
|
|
42
|
+
faiss::Index* index_gpu_to_cpu(const faiss::Index* index);
|
|
43
|
+
|
|
44
|
+
} // namespace gpu_metal
|
|
45
|
+
} // namespace faiss
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// @lint-ignore-every LICENSELINT
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* Metal IVF Flat implementation: GPU-resident IVF list storage and helpers.
|
|
9
|
+
* Mirrors the roles of faiss/gpu/impl/IVFFlat.cuh (storage side only).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
#pragma once
|
|
13
|
+
|
|
14
|
+
#import <Metal/Metal.h>
|
|
15
|
+
|
|
16
|
+
#include <cstddef>
|
|
17
|
+
#include <cstdint>
|
|
18
|
+
#include <memory>
|
|
19
|
+
#include <vector>
|
|
20
|
+
|
|
21
|
+
#include <faiss/Index.h>
|
|
22
|
+
#include <faiss/MetricType.h>
|
|
23
|
+
#include <faiss/gpu/GpuIndicesOptions.h>
|
|
24
|
+
#include <faiss/gpu_metal/MetalResources.h>
|
|
25
|
+
|
|
26
|
+
namespace faiss {
|
|
27
|
+
namespace gpu_metal {
|
|
28
|
+
|
|
29
|
+
/// GPU-resident IVF list storage for flat (float32) codes.
|
|
30
|
+
/// Layout: all lists are stored contiguously in a single codes/ids buffer;
|
|
31
|
+
/// lists are described by (listOffset[list], listLength[list]).
|
|
32
|
+
class MetalIVFFlatImpl {
|
|
33
|
+
public:
|
|
34
|
+
struct AppendDebugStats {
|
|
35
|
+
size_t relayoutEvents = 0;
|
|
36
|
+
size_t movedLists = 0;
|
|
37
|
+
size_t movedVectors = 0;
|
|
38
|
+
size_t reusedSegmentAllocs = 0;
|
|
39
|
+
size_t tailSegmentAllocs = 0;
|
|
40
|
+
size_t reusedCapacityVecs = 0;
|
|
41
|
+
size_t tailCapacityVecs = 0;
|
|
42
|
+
size_t tailShrinkEvents = 0;
|
|
43
|
+
size_t tailShrunkVecs = 0;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
MetalIVFFlatImpl(
|
|
47
|
+
std::shared_ptr<MetalResources> resources,
|
|
48
|
+
int dim,
|
|
49
|
+
idx_t nlist,
|
|
50
|
+
faiss::MetricType metric,
|
|
51
|
+
float metricArg,
|
|
52
|
+
faiss::gpu::IndicesOptions indicesOptions,
|
|
53
|
+
bool interleavedLayout);
|
|
54
|
+
|
|
55
|
+
~MetalIVFFlatImpl();
|
|
56
|
+
|
|
57
|
+
/// Reset all IVF lists and free GPU storage.
|
|
58
|
+
void reset();
|
|
59
|
+
|
|
60
|
+
/// Reserve host/GPU storage for at least totalVecs vectors.
|
|
61
|
+
void reserveMemory(idx_t totalVecs);
|
|
62
|
+
|
|
63
|
+
/// Append a batch of vectors to IVF lists.
|
|
64
|
+
/// - x: host pointer, size n * dim
|
|
65
|
+
/// - list_nos: host pointer, size n; -1 entries are skipped
|
|
66
|
+
/// - xids: host pointer, size n (may be null to use internal ids)
|
|
67
|
+
void appendVectors(
|
|
68
|
+
idx_t n,
|
|
69
|
+
const float* x,
|
|
70
|
+
const idx_t* list_nos,
|
|
71
|
+
const idx_t* xids);
|
|
72
|
+
|
|
73
|
+
/// Accessors for future GPU search path.
|
|
74
|
+
int dim() const {
|
|
75
|
+
return dim_;
|
|
76
|
+
}
|
|
77
|
+
idx_t nlist() const {
|
|
78
|
+
return nlist_;
|
|
79
|
+
}
|
|
80
|
+
faiss::MetricType metricType() const {
|
|
81
|
+
return metric_type_;
|
|
82
|
+
}
|
|
83
|
+
float metricArg() const {
|
|
84
|
+
return metric_arg_;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const std::vector<size_t>& listLength() const {
|
|
88
|
+
return listLength_;
|
|
89
|
+
}
|
|
90
|
+
const std::vector<size_t>& listOffset() const {
|
|
91
|
+
return listOffset_;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
id<MTLBuffer> codesBuffer() const {
|
|
95
|
+
return codesBuffer_;
|
|
96
|
+
}
|
|
97
|
+
id<MTLBuffer> idsBuffer() const {
|
|
98
|
+
return idsBuffer_;
|
|
99
|
+
}
|
|
100
|
+
/// Pre-built GPU buffer of (nlist) uint32_t offsets (updated on every add).
|
|
101
|
+
id<MTLBuffer> listOffsetGpuBuffer() const {
|
|
102
|
+
return listOffsetBuf_;
|
|
103
|
+
}
|
|
104
|
+
/// Pre-built GPU buffer of (nlist) uint32_t lengths (updated on every add).
|
|
105
|
+
id<MTLBuffer> listLengthGpuBuffer() const {
|
|
106
|
+
return listLengthBuf_;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
size_t totalVecs() const {
|
|
110
|
+
return totalVecs_;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/// Interleaved codes buffer (blocks of 32 vectors, dims interleaved).
|
|
114
|
+
id<MTLBuffer> interleavedCodesBuffer() const {
|
|
115
|
+
return interleavedCodesBuf_;
|
|
116
|
+
}
|
|
117
|
+
/// Per-list float offsets into the interleaved codes buffer.
|
|
118
|
+
id<MTLBuffer> interleavedCodesOffsetBuffer() const {
|
|
119
|
+
return interleavedCodesOffsetBuf_;
|
|
120
|
+
}
|
|
121
|
+
bool interleavedLayout() const {
|
|
122
|
+
return interleavedLayout_;
|
|
123
|
+
}
|
|
124
|
+
/// Rebuild interleaved buffers from host storage if they are stale.
|
|
125
|
+
void ensureInterleavedLayoutUpToDate();
|
|
126
|
+
const AppendDebugStats& appendDebugStats() const {
|
|
127
|
+
return appendStats_;
|
|
128
|
+
}
|
|
129
|
+
void resetAppendDebugStats() {
|
|
130
|
+
appendStats_ = AppendDebugStats{};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private:
|
|
134
|
+
struct FreeSegment {
|
|
135
|
+
size_t offset = 0;
|
|
136
|
+
size_t length = 0;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
bool ensureCapacityForAppend_(
|
|
140
|
+
const std::vector<size_t>& addPerList,
|
|
141
|
+
std::vector<uint8_t>* movedLists);
|
|
142
|
+
void uploadToGpu_(
|
|
143
|
+
const std::vector<size_t>& oldLength,
|
|
144
|
+
const std::vector<size_t>& addPerList,
|
|
145
|
+
const std::vector<uint8_t>& movedLists,
|
|
146
|
+
bool forceFullUpload);
|
|
147
|
+
void rebuildInterleavedBuffers_();
|
|
148
|
+
size_t allocSegment_(size_t length);
|
|
149
|
+
void freeSegment_(
|
|
150
|
+
size_t offset,
|
|
151
|
+
size_t length,
|
|
152
|
+
bool allowTailShrink = true);
|
|
153
|
+
void coalesceFreeSegments_();
|
|
154
|
+
void tryShrinkTail_();
|
|
155
|
+
|
|
156
|
+
std::shared_ptr<MetalResources> resources_;
|
|
157
|
+
|
|
158
|
+
int dim_;
|
|
159
|
+
idx_t nlist_;
|
|
160
|
+
faiss::MetricType metric_type_;
|
|
161
|
+
float metric_arg_;
|
|
162
|
+
faiss::gpu::IndicesOptions indicesOptions_;
|
|
163
|
+
bool interleavedLayout_;
|
|
164
|
+
|
|
165
|
+
// Per-list metadata
|
|
166
|
+
std::vector<size_t> listLength_;
|
|
167
|
+
std::vector<size_t> listOffset_;
|
|
168
|
+
std::vector<size_t> listCapacity_;
|
|
169
|
+
|
|
170
|
+
// Host copies of IVF data (flat layout)
|
|
171
|
+
std::vector<float> hostCodes_; // size = totalVecs_ * dim_
|
|
172
|
+
std::vector<idx_t> hostIds_; // size = totalVecs_
|
|
173
|
+
std::vector<FreeSegment> freeSegments_;
|
|
174
|
+
AppendDebugStats appendStats_;
|
|
175
|
+
size_t totalVecs_;
|
|
176
|
+
size_t totalCapacityVecs_;
|
|
177
|
+
|
|
178
|
+
// GPU storage
|
|
179
|
+
id<MTLBuffer> codesBuffer_;
|
|
180
|
+
id<MTLBuffer> idsBuffer_;
|
|
181
|
+
id<MTLBuffer> listOffsetBuf_; // (nlist) uint32_t, list element offsets
|
|
182
|
+
id<MTLBuffer> listLengthBuf_; // (nlist) uint32_t, list sizes
|
|
183
|
+
|
|
184
|
+
// Interleaved codes layout (blocks of 32 vectors, dims interleaved)
|
|
185
|
+
id<MTLBuffer> interleavedCodesBuf_;
|
|
186
|
+
id<MTLBuffer> interleavedCodesOffsetBuf_; // (nlist) uint32_t, float offsets
|
|
187
|
+
bool interleavedDirty_ = true;
|
|
188
|
+
|
|
189
|
+
static constexpr int kInterleavedGroupSize = 32;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
} // namespace gpu_metal
|
|
193
|
+
} // namespace faiss
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// @lint-ignore-every LICENSELINT
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* Metal IVF PQ implementation: GPU-resident IVF list storage for
|
|
9
|
+
* 8-bit product-quantized codes. Each vector is M bytes (one byte
|
|
10
|
+
* per subquantizer, ksub=256).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
#pragma once
|
|
14
|
+
|
|
15
|
+
#import <Metal/Metal.h>
|
|
16
|
+
|
|
17
|
+
#include <cstddef>
|
|
18
|
+
#include <cstdint>
|
|
19
|
+
#include <memory>
|
|
20
|
+
#include <vector>
|
|
21
|
+
|
|
22
|
+
#include <faiss/Index.h>
|
|
23
|
+
#include <faiss/MetricType.h>
|
|
24
|
+
#include <faiss/gpu_metal/MetalResources.h>
|
|
25
|
+
|
|
26
|
+
namespace faiss {
|
|
27
|
+
namespace gpu_metal {
|
|
28
|
+
|
|
29
|
+
class MetalIVFPQImpl {
|
|
30
|
+
public:
|
|
31
|
+
MetalIVFPQImpl(
|
|
32
|
+
std::shared_ptr<MetalResources> resources,
|
|
33
|
+
int dim,
|
|
34
|
+
idx_t nlist,
|
|
35
|
+
int numSubQuantizers,
|
|
36
|
+
int bitsPerCode,
|
|
37
|
+
faiss::MetricType metric,
|
|
38
|
+
float metricArg);
|
|
39
|
+
|
|
40
|
+
~MetalIVFPQImpl();
|
|
41
|
+
|
|
42
|
+
void reset();
|
|
43
|
+
void reserveMemory(idx_t totalVecs);
|
|
44
|
+
|
|
45
|
+
/// Append PQ-encoded vectors. codes: n * codeSize bytes.
|
|
46
|
+
void appendCodes(
|
|
47
|
+
idx_t n,
|
|
48
|
+
const uint8_t* codes,
|
|
49
|
+
const idx_t* list_nos,
|
|
50
|
+
const idx_t* xids);
|
|
51
|
+
|
|
52
|
+
/// Upload PQ centroids: M * ksub * dsub floats, row-major.
|
|
53
|
+
/// Layout: pqCentroids[m][c][dsub_dim]
|
|
54
|
+
void setPQCentroids(const float* centroids);
|
|
55
|
+
|
|
56
|
+
int dim() const {
|
|
57
|
+
return dim_;
|
|
58
|
+
}
|
|
59
|
+
idx_t nlist() const {
|
|
60
|
+
return nlist_;
|
|
61
|
+
}
|
|
62
|
+
int numSubQuantizers() const {
|
|
63
|
+
return M_;
|
|
64
|
+
}
|
|
65
|
+
int bitsPerCode() const {
|
|
66
|
+
return bitsPerCode_;
|
|
67
|
+
}
|
|
68
|
+
int ksub() const {
|
|
69
|
+
return ksub_;
|
|
70
|
+
}
|
|
71
|
+
int dsub() const {
|
|
72
|
+
return dsub_;
|
|
73
|
+
}
|
|
74
|
+
size_t codeSize() const {
|
|
75
|
+
return codeSize_;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const std::vector<size_t>& listLength() const {
|
|
79
|
+
return listLength_;
|
|
80
|
+
}
|
|
81
|
+
const std::vector<size_t>& listOffset() const {
|
|
82
|
+
return listOffset_;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
id<MTLBuffer> codesBuffer() const {
|
|
86
|
+
return codesBuffer_;
|
|
87
|
+
}
|
|
88
|
+
id<MTLBuffer> idsBuffer() const {
|
|
89
|
+
return idsBuffer_;
|
|
90
|
+
}
|
|
91
|
+
id<MTLBuffer> listOffsetGpuBuffer() const {
|
|
92
|
+
return listOffsetBuf_;
|
|
93
|
+
}
|
|
94
|
+
id<MTLBuffer> listLengthGpuBuffer() const {
|
|
95
|
+
return listLengthBuf_;
|
|
96
|
+
}
|
|
97
|
+
id<MTLBuffer> pqCentroidsBuffer() const {
|
|
98
|
+
return pqCentroidsBuf_;
|
|
99
|
+
}
|
|
100
|
+
size_t totalVecs() const {
|
|
101
|
+
return totalVecs_;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private:
|
|
105
|
+
void uploadToGpu();
|
|
106
|
+
|
|
107
|
+
std::shared_ptr<MetalResources> resources_;
|
|
108
|
+
|
|
109
|
+
int dim_;
|
|
110
|
+
idx_t nlist_;
|
|
111
|
+
int M_;
|
|
112
|
+
int bitsPerCode_;
|
|
113
|
+
int ksub_;
|
|
114
|
+
int dsub_;
|
|
115
|
+
size_t codeSize_;
|
|
116
|
+
faiss::MetricType metric_type_;
|
|
117
|
+
float metric_arg_;
|
|
118
|
+
|
|
119
|
+
std::vector<size_t> listLength_;
|
|
120
|
+
std::vector<size_t> listOffset_;
|
|
121
|
+
|
|
122
|
+
std::vector<uint8_t> hostCodes_;
|
|
123
|
+
std::vector<idx_t> hostIds_;
|
|
124
|
+
size_t totalVecs_;
|
|
125
|
+
|
|
126
|
+
id<MTLBuffer> codesBuffer_;
|
|
127
|
+
id<MTLBuffer> idsBuffer_;
|
|
128
|
+
id<MTLBuffer> listOffsetBuf_;
|
|
129
|
+
id<MTLBuffer> listLengthBuf_;
|
|
130
|
+
id<MTLBuffer> pqCentroidsBuf_;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
} // namespace gpu_metal
|
|
134
|
+
} // namespace faiss
|
|
@@ -157,8 +157,8 @@ void ClusteringInitialization::init_centroids(
|
|
|
157
157
|
n,
|
|
158
158
|
k);
|
|
159
159
|
FAISS_THROW_IF_NOT(d > 0);
|
|
160
|
-
FAISS_THROW_IF_NOT(x
|
|
161
|
-
FAISS_THROW_IF_NOT(centroids
|
|
160
|
+
FAISS_THROW_IF_NOT(x);
|
|
161
|
+
FAISS_THROW_IF_NOT(centroids);
|
|
162
162
|
FAISS_THROW_IF_NOT(
|
|
163
163
|
n_existing_centroids == 0 || existing_centroids != nullptr);
|
|
164
164
|
|
|
@@ -130,6 +130,26 @@ struct FlatCodesDistanceComputer : DistanceComputer {
|
|
|
130
130
|
return distance_to_code(codes + i * code_size);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
void distances_batch_4(
|
|
134
|
+
const idx_t idx0,
|
|
135
|
+
const idx_t idx1,
|
|
136
|
+
const idx_t idx2,
|
|
137
|
+
const idx_t idx3,
|
|
138
|
+
float& dis0,
|
|
139
|
+
float& dis1,
|
|
140
|
+
float& dis2,
|
|
141
|
+
float& dis3) override {
|
|
142
|
+
distance_to_code_batch_4(
|
|
143
|
+
codes + idx0 * code_size,
|
|
144
|
+
codes + idx1 * code_size,
|
|
145
|
+
codes + idx2 * code_size,
|
|
146
|
+
codes + idx3 * code_size,
|
|
147
|
+
dis0,
|
|
148
|
+
dis1,
|
|
149
|
+
dis2,
|
|
150
|
+
dis3);
|
|
151
|
+
}
|
|
152
|
+
|
|
133
153
|
/// Computes a partial dot product over a slice of the query vector.
|
|
134
154
|
/// The slice is defined by the following parameters:
|
|
135
155
|
/// — `offset`: the starting index of the first component to include
|
|
@@ -167,6 +187,20 @@ struct FlatCodesDistanceComputer : DistanceComputer {
|
|
|
167
187
|
|
|
168
188
|
/// compute distance of current query to an encoded vector
|
|
169
189
|
virtual float distance_to_code(const uint8_t* code) = 0;
|
|
190
|
+
virtual void distance_to_code_batch_4(
|
|
191
|
+
const uint8_t* c1,
|
|
192
|
+
const uint8_t* c2,
|
|
193
|
+
const uint8_t* c3,
|
|
194
|
+
const uint8_t* c4,
|
|
195
|
+
float& d1,
|
|
196
|
+
float& d2,
|
|
197
|
+
float& d3,
|
|
198
|
+
float& d4) {
|
|
199
|
+
d1 = distance_to_code(c1);
|
|
200
|
+
d2 = distance_to_code(c2);
|
|
201
|
+
d3 = distance_to_code(c3);
|
|
202
|
+
d4 = distance_to_code(c4);
|
|
203
|
+
}
|
|
170
204
|
|
|
171
205
|
/// Compute partial dot products of current query to 4 stored vectors.
|
|
172
206
|
/// See `partial_dot_product` for more details.
|
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <cstddef>
|
|
11
|
+
#include <cstdint>
|
|
12
|
+
|
|
13
|
+
#include <faiss/MetricType.h>
|
|
14
|
+
#include <faiss/impl/DistanceComputer.h>
|
|
15
|
+
#include <faiss/impl/ScalarQuantizer.h>
|
|
16
|
+
#include <faiss/impl/platform_macros.h>
|
|
17
|
+
|
|
18
|
+
namespace faiss {
|
|
19
|
+
|
|
20
|
+
enum EDENScaleType {
|
|
21
|
+
// Original EDEN unbiased scale.
|
|
22
|
+
EDENScaleType_UNBIASED = 1,
|
|
23
|
+
// Biased DRIVE scale (NeurIPS 2021, arXiv:2105.08339), generalized to
|
|
24
|
+
// multi-bit EDEN; see also https://arxiv.org/abs/2604.18555.
|
|
25
|
+
EDENScaleType_BIASED = 2,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
FAISS_PACK_STRUCTS_BEGIN
|
|
29
|
+
struct FAISS_PACKED EDENCodeFactors {
|
|
30
|
+
// L2 term used by the distance computer. For the unbiased scale this is
|
|
31
|
+
// ||r||^2. For the biased scale this is S^2 * ||q_code||^2, the
|
|
32
|
+
// reconstructed-code norm.
|
|
33
|
+
float l2_norm_term = 0;
|
|
34
|
+
// Per-vector reconstruction scale.
|
|
35
|
+
float scale = 0;
|
|
36
|
+
};
|
|
37
|
+
FAISS_PACK_STRUCTS_END
|
|
38
|
+
|
|
39
|
+
struct EDENFlatCodesDistanceComputer : FlatCodesDistanceComputer {
|
|
40
|
+
using FlatCodesDistanceComputer::FlatCodesDistanceComputer;
|
|
41
|
+
|
|
42
|
+
virtual void consecutive_distances_batch_8(idx_t first, float* distances) {
|
|
43
|
+
distances_batch_4(
|
|
44
|
+
first,
|
|
45
|
+
first + 1,
|
|
46
|
+
first + 2,
|
|
47
|
+
first + 3,
|
|
48
|
+
distances[0],
|
|
49
|
+
distances[1],
|
|
50
|
+
distances[2],
|
|
51
|
+
distances[3]);
|
|
52
|
+
distances_batch_4(
|
|
53
|
+
first + 4,
|
|
54
|
+
first + 5,
|
|
55
|
+
first + 6,
|
|
56
|
+
first + 7,
|
|
57
|
+
distances[4],
|
|
58
|
+
distances[5],
|
|
59
|
+
distances[6],
|
|
60
|
+
distances[7]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
virtual void consecutive_distances_batch_16(idx_t first, float* distances) {
|
|
64
|
+
consecutive_distances_batch_8(first, distances);
|
|
65
|
+
consecutive_distances_batch_8(first + 8, distances + 8);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// EDEN Lloyd-Max quantizer from the EDEN ICML 2022 paper:
|
|
70
|
+
// https://proceedings.mlr.press/v162/vargaftik22a.html.
|
|
71
|
+
//
|
|
72
|
+
// EDEN operates on the vectors supplied to it. Optional preprocessing such as
|
|
73
|
+
// a random rotation can be applied externally with IndexPreTransform. The
|
|
74
|
+
// scalar assignment itself is a ScalarQuantizer::QT_*_eden qtype. EDEN adds
|
|
75
|
+
// per-vector scale factors after the packed scalar code and computes them
|
|
76
|
+
// against an externally supplied centroid; nullptr means a zero centroid. The
|
|
77
|
+
// default stored scale is EDEN's original unbiased scale. The biased scale
|
|
78
|
+
// follows DRIVE's MSE-minimizing scale for the chosen Lloyd-Max codeword; see
|
|
79
|
+
// also
|
|
80
|
+
// https://arxiv.org/abs/2604.18555.
|
|
81
|
+
|
|
82
|
+
namespace eden_utils {
|
|
83
|
+
|
|
84
|
+
ScalarQuantizer::QuantizerType quantizer_type_for_bits(size_t nb_bits);
|
|
85
|
+
|
|
86
|
+
bool is_eden_quantizer_type(ScalarQuantizer::QuantizerType qtype);
|
|
87
|
+
|
|
88
|
+
size_t nb_bits_for_qtype(ScalarQuantizer::QuantizerType qtype);
|
|
89
|
+
|
|
90
|
+
size_t packed_code_size(size_t d, size_t nb_bits);
|
|
91
|
+
|
|
92
|
+
size_t code_size(size_t d, size_t nb_bits);
|
|
93
|
+
|
|
94
|
+
uint8_t extract_code(const uint8_t* codes, size_t index, size_t nb_bits);
|
|
95
|
+
|
|
96
|
+
void compute_codes(
|
|
97
|
+
const ScalarQuantizer& sq,
|
|
98
|
+
MetricType metric_type,
|
|
99
|
+
EDENScaleType scale_type,
|
|
100
|
+
const float* x,
|
|
101
|
+
uint8_t* codes,
|
|
102
|
+
size_t n,
|
|
103
|
+
const float* centroid = nullptr);
|
|
104
|
+
|
|
105
|
+
void decode(
|
|
106
|
+
const ScalarQuantizer& sq,
|
|
107
|
+
const uint8_t* codes,
|
|
108
|
+
float* x,
|
|
109
|
+
size_t n,
|
|
110
|
+
const float* centroid = nullptr);
|
|
111
|
+
|
|
112
|
+
EDENFlatCodesDistanceComputer* get_distance_computer(
|
|
113
|
+
const ScalarQuantizer& sq,
|
|
114
|
+
MetricType metric_type,
|
|
115
|
+
const float* centroid = nullptr);
|
|
116
|
+
|
|
117
|
+
} // namespace eden_utils
|
|
118
|
+
|
|
119
|
+
} // namespace faiss
|