faiss 0.2.0 → 0.2.1
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 +4 -0
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +292 -291
- data/vendor/faiss/faiss/AutoTune.h +55 -56
- data/vendor/faiss/faiss/Clustering.cpp +334 -195
- data/vendor/faiss/faiss/Clustering.h +88 -35
- data/vendor/faiss/faiss/IVFlib.cpp +171 -195
- data/vendor/faiss/faiss/IVFlib.h +48 -51
- data/vendor/faiss/faiss/Index.cpp +85 -103
- data/vendor/faiss/faiss/Index.h +54 -48
- data/vendor/faiss/faiss/Index2Layer.cpp +139 -164
- data/vendor/faiss/faiss/Index2Layer.h +22 -22
- data/vendor/faiss/faiss/IndexBinary.cpp +45 -37
- data/vendor/faiss/faiss/IndexBinary.h +140 -132
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +73 -53
- data/vendor/faiss/faiss/IndexBinaryFlat.h +29 -24
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +46 -43
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +16 -15
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +215 -232
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +25 -24
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +182 -177
- data/vendor/faiss/faiss/IndexBinaryHash.h +41 -34
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +489 -461
- data/vendor/faiss/faiss/IndexBinaryIVF.h +97 -68
- data/vendor/faiss/faiss/IndexFlat.cpp +116 -147
- data/vendor/faiss/faiss/IndexFlat.h +35 -46
- data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
- data/vendor/faiss/faiss/IndexHNSW.h +57 -41
- data/vendor/faiss/faiss/IndexIVF.cpp +474 -454
- data/vendor/faiss/faiss/IndexIVF.h +146 -113
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +248 -250
- data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +457 -516
- data/vendor/faiss/faiss/IndexIVFPQ.h +74 -66
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +406 -372
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +82 -57
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +104 -102
- data/vendor/faiss/faiss/IndexIVFPQR.h +33 -28
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +125 -133
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +19 -21
- data/vendor/faiss/faiss/IndexLSH.cpp +75 -96
- data/vendor/faiss/faiss/IndexLSH.h +21 -26
- data/vendor/faiss/faiss/IndexLattice.cpp +42 -56
- data/vendor/faiss/faiss/IndexLattice.h +11 -16
- data/vendor/faiss/faiss/IndexNNDescent.cpp +231 -0
- data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
- data/vendor/faiss/faiss/IndexNSG.cpp +303 -0
- data/vendor/faiss/faiss/IndexNSG.h +85 -0
- data/vendor/faiss/faiss/IndexPQ.cpp +405 -464
- data/vendor/faiss/faiss/IndexPQ.h +64 -67
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +143 -170
- data/vendor/faiss/faiss/IndexPQFastScan.h +46 -32
- data/vendor/faiss/faiss/IndexPreTransform.cpp +120 -150
- data/vendor/faiss/faiss/IndexPreTransform.h +33 -36
- data/vendor/faiss/faiss/IndexRefine.cpp +115 -131
- data/vendor/faiss/faiss/IndexRefine.h +22 -23
- data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
- data/vendor/faiss/faiss/IndexReplicas.h +62 -56
- data/vendor/faiss/faiss/IndexResidual.cpp +291 -0
- data/vendor/faiss/faiss/IndexResidual.h +152 -0
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +120 -155
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -45
- data/vendor/faiss/faiss/IndexShards.cpp +256 -240
- data/vendor/faiss/faiss/IndexShards.h +85 -73
- data/vendor/faiss/faiss/MatrixStats.cpp +112 -97
- data/vendor/faiss/faiss/MatrixStats.h +7 -10
- data/vendor/faiss/faiss/MetaIndexes.cpp +135 -157
- data/vendor/faiss/faiss/MetaIndexes.h +40 -34
- data/vendor/faiss/faiss/MetricType.h +7 -7
- data/vendor/faiss/faiss/VectorTransform.cpp +652 -474
- data/vendor/faiss/faiss/VectorTransform.h +61 -89
- data/vendor/faiss/faiss/clone_index.cpp +77 -73
- data/vendor/faiss/faiss/clone_index.h +4 -9
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +33 -38
- data/vendor/faiss/faiss/gpu/GpuAutoTune.h +11 -9
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +197 -170
- data/vendor/faiss/faiss/gpu/GpuCloner.h +53 -35
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +12 -14
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +27 -25
- data/vendor/faiss/faiss/gpu/GpuDistance.h +116 -112
- data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -2
- data/vendor/faiss/faiss/gpu/GpuIndex.h +134 -137
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +76 -73
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +173 -162
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +67 -64
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +89 -86
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +150 -141
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +101 -103
- data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +17 -16
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +116 -128
- data/vendor/faiss/faiss/gpu/GpuResources.h +182 -186
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +433 -422
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +131 -130
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +468 -456
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +25 -19
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +22 -20
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +9 -8
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +39 -44
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +16 -14
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +77 -71
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +109 -88
- data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +75 -64
- data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +230 -215
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +80 -86
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +284 -277
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +416 -416
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +611 -517
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +166 -164
- data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +61 -53
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +274 -238
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +73 -57
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +47 -50
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +79 -72
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +140 -146
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +69 -71
- data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +21 -16
- data/vendor/faiss/faiss/gpu/utils/Timer.cpp +25 -29
- data/vendor/faiss/faiss/gpu/utils/Timer.h +30 -29
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +270 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +115 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +90 -120
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +81 -65
- data/vendor/faiss/faiss/impl/FaissAssert.h +73 -58
- data/vendor/faiss/faiss/impl/FaissException.cpp +56 -48
- data/vendor/faiss/faiss/impl/FaissException.h +41 -29
- data/vendor/faiss/faiss/impl/HNSW.cpp +595 -611
- data/vendor/faiss/faiss/impl/HNSW.h +179 -200
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +672 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +172 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +487 -0
- data/vendor/faiss/faiss/impl/NNDescent.h +154 -0
- data/vendor/faiss/faiss/impl/NSG.cpp +682 -0
- data/vendor/faiss/faiss/impl/NSG.h +199 -0
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +484 -454
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +52 -55
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +26 -47
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +469 -459
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +76 -87
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +448 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +130 -0
- data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +648 -701
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +48 -46
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +129 -131
- data/vendor/faiss/faiss/impl/ThreadedIndex.h +61 -55
- data/vendor/faiss/faiss/impl/index_read.cpp +547 -479
- data/vendor/faiss/faiss/impl/index_write.cpp +497 -407
- data/vendor/faiss/faiss/impl/io.cpp +75 -94
- data/vendor/faiss/faiss/impl/io.h +31 -41
- data/vendor/faiss/faiss/impl/io_macros.h +40 -29
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +137 -186
- data/vendor/faiss/faiss/impl/lattice_Zn.h +40 -51
- data/vendor/faiss/faiss/impl/platform_macros.h +29 -8
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +77 -124
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +39 -48
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +41 -52
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +80 -117
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +109 -137
- data/vendor/faiss/faiss/index_factory.cpp +269 -218
- data/vendor/faiss/faiss/index_factory.h +6 -7
- data/vendor/faiss/faiss/index_io.h +23 -26
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +67 -75
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +22 -24
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +96 -112
- data/vendor/faiss/faiss/invlists/DirectMap.h +29 -33
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +307 -364
- data/vendor/faiss/faiss/invlists/InvertedLists.h +151 -151
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +29 -34
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +17 -18
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +257 -293
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +50 -45
- data/vendor/faiss/faiss/python/python_callbacks.cpp +23 -26
- data/vendor/faiss/faiss/python/python_callbacks.h +9 -16
- data/vendor/faiss/faiss/utils/AlignedTable.h +79 -44
- data/vendor/faiss/faiss/utils/Heap.cpp +40 -48
- data/vendor/faiss/faiss/utils/Heap.h +186 -209
- data/vendor/faiss/faiss/utils/WorkerThread.cpp +67 -76
- data/vendor/faiss/faiss/utils/WorkerThread.h +32 -33
- data/vendor/faiss/faiss/utils/distances.cpp +301 -310
- data/vendor/faiss/faiss/utils/distances.h +133 -118
- data/vendor/faiss/faiss/utils/distances_simd.cpp +456 -516
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +117 -0
- data/vendor/faiss/faiss/utils/extra_distances.cpp +113 -232
- data/vendor/faiss/faiss/utils/extra_distances.h +30 -29
- data/vendor/faiss/faiss/utils/hamming-inl.h +260 -209
- data/vendor/faiss/faiss/utils/hamming.cpp +375 -469
- data/vendor/faiss/faiss/utils/hamming.h +62 -85
- data/vendor/faiss/faiss/utils/ordered_key_value.h +16 -18
- data/vendor/faiss/faiss/utils/partitioning.cpp +393 -318
- data/vendor/faiss/faiss/utils/partitioning.h +26 -21
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +78 -66
- data/vendor/faiss/faiss/utils/quantize_lut.h +22 -20
- data/vendor/faiss/faiss/utils/random.cpp +39 -63
- data/vendor/faiss/faiss/utils/random.h +13 -16
- data/vendor/faiss/faiss/utils/simdlib.h +4 -2
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +88 -85
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +226 -165
- data/vendor/faiss/faiss/utils/simdlib_neon.h +832 -0
- data/vendor/faiss/faiss/utils/utils.cpp +304 -287
- data/vendor/faiss/faiss/utils/utils.h +53 -48
- metadata +20 -2
|
@@ -13,23 +13,24 @@
|
|
|
13
13
|
|
|
14
14
|
#include <faiss/IndexIVFPQ.h>
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
namespace faiss {
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
18
|
/** Index with an additional level of PQ refinement */
|
|
22
|
-
struct IndexIVFPQR: IndexIVFPQ {
|
|
23
|
-
ProductQuantizer refine_pq;
|
|
24
|
-
std::vector
|
|
19
|
+
struct IndexIVFPQR : IndexIVFPQ {
|
|
20
|
+
ProductQuantizer refine_pq; ///< 3rd level quantizer
|
|
21
|
+
std::vector<uint8_t> refine_codes; ///< corresponding codes
|
|
25
22
|
|
|
26
23
|
/// factor between k requested in search and the k requested from the IVFPQ
|
|
27
24
|
float k_factor;
|
|
28
25
|
|
|
29
|
-
IndexIVFPQR
|
|
30
|
-
Index
|
|
31
|
-
size_t
|
|
32
|
-
size_t
|
|
26
|
+
IndexIVFPQR(
|
|
27
|
+
Index* quantizer,
|
|
28
|
+
size_t d,
|
|
29
|
+
size_t nlist,
|
|
30
|
+
size_t M,
|
|
31
|
+
size_t nbits_per_idx,
|
|
32
|
+
size_t M_refine,
|
|
33
|
+
size_t nbits_per_idx_refine);
|
|
33
34
|
|
|
34
35
|
void reset() override;
|
|
35
36
|
|
|
@@ -41,26 +42,30 @@ struct IndexIVFPQR: IndexIVFPQ {
|
|
|
41
42
|
void add_with_ids(idx_t n, const float* x, const idx_t* xids) override;
|
|
42
43
|
|
|
43
44
|
/// same as add_with_ids, but optionally use the precomputed list ids
|
|
44
|
-
void add_core
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
void
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
void
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
45
|
+
void add_core(
|
|
46
|
+
idx_t n,
|
|
47
|
+
const float* x,
|
|
48
|
+
const idx_t* xids,
|
|
49
|
+
const idx_t* precomputed_idx) override;
|
|
50
|
+
|
|
51
|
+
void reconstruct_from_offset(int64_t list_no, int64_t offset, float* recons)
|
|
52
|
+
const override;
|
|
53
|
+
|
|
54
|
+
void merge_from(IndexIVF& other, idx_t add_id) override;
|
|
55
|
+
|
|
56
|
+
void search_preassigned(
|
|
57
|
+
idx_t n,
|
|
58
|
+
const float* x,
|
|
59
|
+
idx_t k,
|
|
60
|
+
const idx_t* assign,
|
|
61
|
+
const float* centroid_dis,
|
|
62
|
+
float* distances,
|
|
63
|
+
idx_t* labels,
|
|
64
|
+
bool store_pairs,
|
|
65
|
+
const IVFSearchParameters* params = nullptr,
|
|
66
|
+
IndexIVFStats* stats = nullptr) const override;
|
|
61
67
|
|
|
62
68
|
IndexIVFPQR();
|
|
63
69
|
};
|
|
64
70
|
|
|
65
|
-
|
|
66
71
|
} // namespace faiss
|
|
@@ -7,43 +7,47 @@
|
|
|
7
7
|
|
|
8
8
|
// -*- c++ -*-
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
#include <faiss/IndexIVFSpectralHash.h>
|
|
12
11
|
|
|
13
|
-
#include <memory>
|
|
14
|
-
#include <algorithm>
|
|
15
12
|
#include <stdint.h>
|
|
13
|
+
#include <algorithm>
|
|
14
|
+
#include <memory>
|
|
16
15
|
|
|
16
|
+
#include <faiss/VectorTransform.h>
|
|
17
|
+
#include <faiss/impl/AuxIndexStructures.h>
|
|
18
|
+
#include <faiss/impl/FaissAssert.h>
|
|
17
19
|
#include <faiss/utils/hamming.h>
|
|
18
20
|
#include <faiss/utils/utils.h>
|
|
19
|
-
#include <faiss/impl/FaissAssert.h>
|
|
20
|
-
#include <faiss/impl/AuxIndexStructures.h>
|
|
21
|
-
#include <faiss/VectorTransform.h>
|
|
22
21
|
|
|
23
22
|
namespace faiss {
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
IndexIVFSpectralHash::IndexIVFSpectralHash(
|
|
25
|
+
Index* quantizer,
|
|
26
|
+
size_t d,
|
|
27
|
+
size_t nlist,
|
|
28
|
+
int nbit,
|
|
29
|
+
float period)
|
|
30
|
+
: IndexIVF(quantizer, d, nlist, (nbit + 7) / 8, METRIC_L2),
|
|
31
|
+
nbit(nbit),
|
|
32
|
+
period(period),
|
|
33
|
+
threshold_type(Thresh_global) {
|
|
34
|
+
FAISS_THROW_IF_NOT(code_size % 4 == 0);
|
|
35
|
+
RandomRotationMatrix* rr = new RandomRotationMatrix(d, nbit);
|
|
36
|
+
rr->init(1234);
|
|
35
37
|
vt = rr;
|
|
36
38
|
own_fields = true;
|
|
37
39
|
is_trained = false;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
IndexIVFSpectralHash::IndexIVFSpectralHash()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
IndexIVFSpectralHash::IndexIVFSpectralHash()
|
|
43
|
+
: IndexIVF(),
|
|
44
|
+
vt(nullptr),
|
|
45
|
+
own_fields(false),
|
|
46
|
+
nbit(0),
|
|
47
|
+
period(0),
|
|
48
|
+
threshold_type(Thresh_global) {}
|
|
44
49
|
|
|
45
|
-
IndexIVFSpectralHash::~IndexIVFSpectralHash
|
|
46
|
-
{
|
|
50
|
+
IndexIVFSpectralHash::~IndexIVFSpectralHash() {
|
|
47
51
|
if (own_fields) {
|
|
48
52
|
delete vt;
|
|
49
53
|
}
|
|
@@ -51,35 +55,33 @@ IndexIVFSpectralHash::~IndexIVFSpectralHash ()
|
|
|
51
55
|
|
|
52
56
|
namespace {
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
float median (size_t n, float *x) {
|
|
58
|
+
float median(size_t n, float* x) {
|
|
56
59
|
std::sort(x, x + n);
|
|
57
60
|
if (n % 2 == 1) {
|
|
58
|
-
return x
|
|
61
|
+
return x[n / 2];
|
|
59
62
|
} else {
|
|
60
|
-
return (x
|
|
63
|
+
return (x[n / 2 - 1] + x[n / 2]) / 2;
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
|
|
64
|
-
}
|
|
65
|
-
|
|
67
|
+
} // namespace
|
|
66
68
|
|
|
67
|
-
void IndexIVFSpectralHash::train_residual
|
|
68
|
-
{
|
|
69
|
+
void IndexIVFSpectralHash::train_residual(idx_t n, const float* x) {
|
|
69
70
|
if (!vt->is_trained) {
|
|
70
|
-
vt->train
|
|
71
|
+
vt->train(n, x);
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
if (threshold_type == Thresh_global) {
|
|
74
75
|
// nothing to do
|
|
75
76
|
return;
|
|
76
|
-
} else if (
|
|
77
|
-
|
|
77
|
+
} else if (
|
|
78
|
+
threshold_type == Thresh_centroid ||
|
|
79
|
+
threshold_type == Thresh_centroid_half) {
|
|
78
80
|
// convert all centroids with vt
|
|
79
|
-
std::vector<float> centroids
|
|
80
|
-
quantizer->reconstruct_n
|
|
81
|
+
std::vector<float> centroids(nlist * d);
|
|
82
|
+
quantizer->reconstruct_n(0, nlist, centroids.data());
|
|
81
83
|
trained.resize(nlist * nbit);
|
|
82
|
-
vt->apply_noalloc
|
|
84
|
+
vt->apply_noalloc(nlist, centroids.data(), trained.data());
|
|
83
85
|
if (threshold_type == Thresh_centroid_half) {
|
|
84
86
|
for (size_t i = 0; i < nlist * nbit; i++) {
|
|
85
87
|
trained[i] -= 0.25 * period;
|
|
@@ -90,12 +92,12 @@ void IndexIVFSpectralHash::train_residual (idx_t n, const float *x)
|
|
|
90
92
|
// otherwise train medians
|
|
91
93
|
|
|
92
94
|
// assign
|
|
93
|
-
std::unique_ptr<idx_t
|
|
94
|
-
quantizer->assign
|
|
95
|
+
std::unique_ptr<idx_t[]> idx(new idx_t[n]);
|
|
96
|
+
quantizer->assign(n, x, idx.get());
|
|
95
97
|
|
|
96
98
|
std::vector<size_t> sizes(nlist + 1);
|
|
97
99
|
for (size_t i = 0; i < n; i++) {
|
|
98
|
-
FAISS_THROW_IF_NOT
|
|
100
|
+
FAISS_THROW_IF_NOT(idx[i] >= 0);
|
|
99
101
|
sizes[idx[i]]++;
|
|
100
102
|
}
|
|
101
103
|
|
|
@@ -107,10 +109,10 @@ void IndexIVFSpectralHash::train_residual (idx_t n, const float *x)
|
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
// transform
|
|
110
|
-
std::unique_ptr<float
|
|
112
|
+
std::unique_ptr<float[]> xt(vt->apply(n, x));
|
|
111
113
|
|
|
112
114
|
// transpose + reorder
|
|
113
|
-
std::unique_ptr<float
|
|
115
|
+
std::unique_ptr<float[]> xo(new float[n * nbit]);
|
|
114
116
|
|
|
115
117
|
for (size_t i = 0; i < n; i++) {
|
|
116
118
|
size_t idest = sizes[idx[i]]++;
|
|
@@ -119,14 +121,14 @@ void IndexIVFSpectralHash::train_residual (idx_t n, const float *x)
|
|
|
119
121
|
}
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
trained.resize
|
|
124
|
+
trained.resize(n * nbit);
|
|
123
125
|
// compute medians
|
|
124
126
|
#pragma omp for
|
|
125
127
|
for (int i = 0; i < nlist; i++) {
|
|
126
128
|
size_t i0 = i == 0 ? 0 : sizes[i - 1];
|
|
127
129
|
size_t i1 = sizes[i];
|
|
128
130
|
for (int j = 0; j < nbit; j++) {
|
|
129
|
-
float
|
|
131
|
+
float* xoi = xo.get() + i0 + n * j;
|
|
130
132
|
if (i0 == i1) { // nothing to train
|
|
131
133
|
trained[i * nbit + j] = 0.0;
|
|
132
134
|
} else if (i1 == i0 + 1) {
|
|
@@ -138,14 +140,15 @@ void IndexIVFSpectralHash::train_residual (idx_t n, const float *x)
|
|
|
138
140
|
}
|
|
139
141
|
}
|
|
140
142
|
|
|
141
|
-
|
|
142
143
|
namespace {
|
|
143
144
|
|
|
144
|
-
void binarize_with_freq(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
void binarize_with_freq(
|
|
146
|
+
size_t nbit,
|
|
147
|
+
float freq,
|
|
148
|
+
const float* x,
|
|
149
|
+
const float* c,
|
|
150
|
+
uint8_t* codes) {
|
|
151
|
+
memset(codes, 0, (nbit + 7) / 8);
|
|
149
152
|
for (size_t i = 0; i < nbit; i++) {
|
|
150
153
|
float xf = (x[i] - c[i]);
|
|
151
154
|
int xi = int(floor(xf * freq));
|
|
@@ -154,43 +157,44 @@ void binarize_with_freq(size_t nbit, float freq,
|
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
159
|
|
|
160
|
+
}; // namespace
|
|
157
161
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
bool include_listnos) const
|
|
166
|
-
{
|
|
167
|
-
FAISS_THROW_IF_NOT (is_trained);
|
|
162
|
+
void IndexIVFSpectralHash::encode_vectors(
|
|
163
|
+
idx_t n,
|
|
164
|
+
const float* x_in,
|
|
165
|
+
const idx_t* list_nos,
|
|
166
|
+
uint8_t* codes,
|
|
167
|
+
bool include_listnos) const {
|
|
168
|
+
FAISS_THROW_IF_NOT(is_trained);
|
|
168
169
|
float freq = 2.0 / period;
|
|
169
170
|
|
|
170
|
-
FAISS_THROW_IF_NOT_MSG
|
|
171
|
+
FAISS_THROW_IF_NOT_MSG(!include_listnos, "listnos encoding not supported");
|
|
171
172
|
|
|
172
173
|
// transform with vt
|
|
173
|
-
std::unique_ptr<float
|
|
174
|
+
std::unique_ptr<float[]> x(vt->apply(n, x_in));
|
|
174
175
|
|
|
175
176
|
#pragma omp parallel
|
|
176
177
|
{
|
|
177
|
-
std::vector<float> zero
|
|
178
|
+
std::vector<float> zero(nbit);
|
|
178
179
|
|
|
179
180
|
// each thread takes care of a subset of lists
|
|
180
181
|
#pragma omp for
|
|
181
182
|
for (idx_t i = 0; i < n; i++) {
|
|
182
|
-
int64_t list_no = list_nos
|
|
183
|
+
int64_t list_no = list_nos[i];
|
|
183
184
|
|
|
184
185
|
if (list_no >= 0) {
|
|
185
|
-
const float
|
|
186
|
+
const float* c;
|
|
186
187
|
if (threshold_type == Thresh_global) {
|
|
187
188
|
c = zero.data();
|
|
188
189
|
} else {
|
|
189
190
|
c = trained.data() + list_no * nbit;
|
|
190
191
|
}
|
|
191
|
-
binarize_with_freq
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
binarize_with_freq(
|
|
193
|
+
nbit,
|
|
194
|
+
freq,
|
|
195
|
+
x.get() + i * nbit,
|
|
196
|
+
c,
|
|
197
|
+
codes + i * code_size);
|
|
194
198
|
}
|
|
195
199
|
}
|
|
196
200
|
}
|
|
@@ -198,12 +202,10 @@ void IndexIVFSpectralHash::encode_vectors(idx_t n, const float* x_in,
|
|
|
198
202
|
|
|
199
203
|
namespace {
|
|
200
204
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
struct IVFScanner: InvertedListScanner {
|
|
204
|
-
|
|
205
|
+
template <class HammingComputer>
|
|
206
|
+
struct IVFScanner : InvertedListScanner {
|
|
205
207
|
// copied from index structure
|
|
206
|
-
const IndexIVFSpectralHash
|
|
208
|
+
const IndexIVFSpectralHash* index;
|
|
207
209
|
size_t code_size;
|
|
208
210
|
size_t nbit;
|
|
209
211
|
bool store_pairs;
|
|
@@ -216,61 +218,58 @@ struct IVFScanner: InvertedListScanner {
|
|
|
216
218
|
|
|
217
219
|
using idx_t = Index::idx_t;
|
|
218
220
|
|
|
219
|
-
IVFScanner
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
void set_query (const float *query) override {
|
|
221
|
+
IVFScanner(const IndexIVFSpectralHash* index, bool store_pairs)
|
|
222
|
+
: index(index),
|
|
223
|
+
code_size(index->code_size),
|
|
224
|
+
nbit(index->nbit),
|
|
225
|
+
store_pairs(store_pairs),
|
|
226
|
+
period(index->period),
|
|
227
|
+
freq(2.0 / index->period),
|
|
228
|
+
q(nbit),
|
|
229
|
+
zero(nbit),
|
|
230
|
+
qcode(code_size),
|
|
231
|
+
hc(qcode.data(), code_size) {}
|
|
232
|
+
|
|
233
|
+
void set_query(const float* query) override {
|
|
233
234
|
FAISS_THROW_IF_NOT(query);
|
|
234
235
|
FAISS_THROW_IF_NOT(q.size() == nbit);
|
|
235
|
-
index->vt->apply_noalloc
|
|
236
|
+
index->vt->apply_noalloc(1, query, q.data());
|
|
236
237
|
|
|
237
|
-
if (index->threshold_type ==
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
(nbit, freq, q.data(), zero.data(), qcode.data());
|
|
241
|
-
hc.set (qcode.data(), code_size);
|
|
238
|
+
if (index->threshold_type == IndexIVFSpectralHash::Thresh_global) {
|
|
239
|
+
binarize_with_freq(nbit, freq, q.data(), zero.data(), qcode.data());
|
|
240
|
+
hc.set(qcode.data(), code_size);
|
|
242
241
|
}
|
|
243
242
|
}
|
|
244
243
|
|
|
245
244
|
idx_t list_no;
|
|
246
245
|
|
|
247
|
-
void set_list
|
|
246
|
+
void set_list(idx_t list_no, float /*coarse_dis*/) override {
|
|
248
247
|
this->list_no = list_no;
|
|
249
248
|
if (index->threshold_type != IndexIVFSpectralHash::Thresh_global) {
|
|
250
|
-
const float
|
|
251
|
-
binarize_with_freq
|
|
252
|
-
hc.set
|
|
249
|
+
const float* c = index->trained.data() + list_no * nbit;
|
|
250
|
+
binarize_with_freq(nbit, freq, q.data(), c, qcode.data());
|
|
251
|
+
hc.set(qcode.data(), code_size);
|
|
253
252
|
}
|
|
254
253
|
}
|
|
255
254
|
|
|
256
|
-
float distance_to_code
|
|
257
|
-
return hc.hamming
|
|
255
|
+
float distance_to_code(const uint8_t* code) const final {
|
|
256
|
+
return hc.hamming(code);
|
|
258
257
|
}
|
|
259
258
|
|
|
260
|
-
size_t scan_codes
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
259
|
+
size_t scan_codes(
|
|
260
|
+
size_t list_size,
|
|
261
|
+
const uint8_t* codes,
|
|
262
|
+
const idx_t* ids,
|
|
263
|
+
float* simi,
|
|
264
|
+
idx_t* idxi,
|
|
265
|
+
size_t k) const override {
|
|
266
266
|
size_t nup = 0;
|
|
267
267
|
for (size_t j = 0; j < list_size; j++) {
|
|
268
|
+
float dis = hc.hamming(codes);
|
|
268
269
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
int64_t id = store_pairs ? lo_build (list_no, j) : ids[j];
|
|
273
|
-
maxheap_replace_top (k, simi, idxi, dis, id);
|
|
270
|
+
if (dis < simi[0]) {
|
|
271
|
+
int64_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
272
|
+
maxheap_replace_top(k, simi, idxi, dis, id);
|
|
274
273
|
nup++;
|
|
275
274
|
}
|
|
276
275
|
codes += code_size;
|
|
@@ -278,34 +277,31 @@ struct IVFScanner: InvertedListScanner {
|
|
|
278
277
|
return nup;
|
|
279
278
|
}
|
|
280
279
|
|
|
281
|
-
void scan_codes_range
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
280
|
+
void scan_codes_range(
|
|
281
|
+
size_t list_size,
|
|
282
|
+
const uint8_t* codes,
|
|
283
|
+
const idx_t* ids,
|
|
284
|
+
float radius,
|
|
285
|
+
RangeQueryResult& res) const override {
|
|
287
286
|
for (size_t j = 0; j < list_size; j++) {
|
|
288
|
-
float dis = hc.hamming
|
|
287
|
+
float dis = hc.hamming(codes);
|
|
289
288
|
if (dis < radius) {
|
|
290
|
-
int64_t id = store_pairs ? lo_build
|
|
291
|
-
res.add
|
|
289
|
+
int64_t id = store_pairs ? lo_build(list_no, j) : ids[j];
|
|
290
|
+
res.add(dis, id);
|
|
292
291
|
}
|
|
293
292
|
codes += code_size;
|
|
294
293
|
}
|
|
295
294
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
295
|
};
|
|
299
296
|
|
|
300
297
|
} // anonymous namespace
|
|
301
298
|
|
|
302
|
-
InvertedListScanner* IndexIVFSpectralHash::get_InvertedListScanner
|
|
303
|
-
|
|
304
|
-
{
|
|
299
|
+
InvertedListScanner* IndexIVFSpectralHash::get_InvertedListScanner(
|
|
300
|
+
bool store_pairs) const {
|
|
305
301
|
switch (code_size) {
|
|
306
302
|
#define HANDLE_CODE_SIZE(cs) \
|
|
307
|
-
case cs:
|
|
308
|
-
return new IVFScanner<HammingComputer
|
|
303
|
+
case cs: \
|
|
304
|
+
return new IVFScanner<HammingComputer##cs>(this, store_pairs)
|
|
309
305
|
HANDLE_CODE_SIZE(4);
|
|
310
306
|
HANDLE_CODE_SIZE(8);
|
|
311
307
|
HANDLE_CODE_SIZE(16);
|
|
@@ -314,17 +310,13 @@ InvertedListScanner* IndexIVFSpectralHash::get_InvertedListScanner
|
|
|
314
310
|
HANDLE_CODE_SIZE(64);
|
|
315
311
|
#undef HANDLE_CODE_SIZE
|
|
316
312
|
default:
|
|
317
|
-
if (code_size %
|
|
318
|
-
return new IVFScanner<
|
|
319
|
-
|
|
320
|
-
return new IVFScanner<HammingComputerM4>(this, store_pairs);
|
|
313
|
+
if (code_size % 4 == 0) {
|
|
314
|
+
return new IVFScanner<HammingComputerDefault>(
|
|
315
|
+
this, store_pairs);
|
|
321
316
|
} else {
|
|
322
317
|
FAISS_THROW_MSG("not supported");
|
|
323
318
|
}
|
|
324
319
|
}
|
|
325
|
-
|
|
326
320
|
}
|
|
327
321
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
} // namespace faiss
|
|
322
|
+
} // namespace faiss
|