faiss 0.6.3 → 0.6.4
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/Clustering.h +8 -0
- data/vendor/faiss/faiss/Index.h +1 -1
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +23 -2
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +12 -140
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +0 -6
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +6 -14
- data/vendor/faiss/faiss/IndexBinaryIVF.h +8 -1
- data/vendor/faiss/faiss/IndexFlat.cpp +8 -4
- data/vendor/faiss/faiss/IndexFlat.h +2 -2
- data/vendor/faiss/faiss/IndexHNSW.cpp +301 -91
- data/vendor/faiss/faiss/IndexHNSW.h +31 -7
- data/vendor/faiss/faiss/IndexIDMap.cpp +11 -6
- data/vendor/faiss/faiss/IndexIVF.cpp +19 -4
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +9 -1
- data/vendor/faiss/faiss/IndexIVFPQ.h +11 -0
- data/vendor/faiss/faiss/IndexShards.cpp +3 -3
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +4 -3
- data/vendor/faiss/faiss/SuperKMeans.cpp +31 -8
- data/vendor/faiss/faiss/SuperKMeans.h +3 -2
- data/vendor/faiss/faiss/VectorTransform.cpp +38 -0
- data/vendor/faiss/faiss/VectorTransform.h +3 -0
- data/vendor/faiss/faiss/clone_index.cpp +3 -0
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +1 -5
- data/vendor/faiss/faiss/gpu/GpuDistance.h +2 -5
- data/vendor/faiss/faiss/gpu/GpuIndex.h +4 -5
- data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +65 -42
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +1 -1
- data/vendor/faiss/faiss/impl/ClusteringInitialization.cpp +5 -2
- data/vendor/faiss/faiss/impl/HNSW.cpp +419 -115
- data/vendor/faiss/faiss/impl/HNSW.h +46 -7
- data/vendor/faiss/faiss/impl/IDSelector.h +44 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +10 -3
- data/vendor/faiss/faiss/impl/Panorama.h +11 -2
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +4 -4
- data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +1 -1
- data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +74 -8
- data/vendor/faiss/faiss/impl/RaBitQuantizer.h +47 -4
- data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +2 -2
- data/vendor/faiss/faiss/impl/ResultHandler.h +9 -3
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +32 -30
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +6 -10
- data/vendor/faiss/faiss/impl/binary_hamming/IndexBinaryIVF_impl.h +89 -13
- data/vendor/faiss/faiss/impl/expanded_scanners.h +5 -1
- data/vendor/faiss/faiss/impl/fast_scan/decompose_qbs.h +1 -0
- data/vendor/faiss/faiss/impl/index_read.cpp +130 -29
- data/vendor/faiss/faiss/impl/index_write.cpp +31 -26
- data/vendor/faiss/faiss/impl/pq_code_distance/IVFPQScanner_impl.h +73 -39
- data/vendor/faiss/faiss/impl/pq_code_distance/pq_code_distance-generic.cpp +4 -4
- data/vendor/faiss/faiss/impl/scalar_quantizer/EDENQuantizer.cpp +6 -1
- data/vendor/faiss/faiss/impl/scalar_quantizer/distance_computers.h +2 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-avx2.cpp +6 -2
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-dispatch.h +37 -17
- data/vendor/faiss/faiss/impl/scalar_quantizer/sq-neon.cpp +109 -10
- data/vendor/faiss/faiss/impl/simd_dispatch.h +40 -22
- data/vendor/faiss/faiss/index_factory.cpp +8 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +7 -4
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +10 -4
- data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +16 -4
- data/vendor/faiss/faiss/svs/IndexSVSVamana.h +8 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +4 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +2 -1
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +9 -2
- data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +2 -1
- data/vendor/faiss/faiss/utils/distances.cpp +20 -13
- data/vendor/faiss/faiss/utils/distances_dispatch.h +30 -24
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +1 -1
- data/vendor/faiss/faiss/utils/hamming.cpp +15 -9
- data/vendor/faiss/faiss/utils/hamming.h +10 -1
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +14 -3
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_vpopcnt.cpp +24 -0
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_computer-avx512.h +1 -1
- data/vendor/faiss/faiss/utils/hamming_distance/{hamming_computer-avx512_spr.h → hamming_computer-avx512_vpopcnt.h} +85 -24
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_impl.h +141 -0
- data/vendor/faiss/faiss/utils/simd_impl/distances_arm_sve.cpp +194 -30
- data/vendor/faiss/faiss/utils/simd_impl/distances_rvv.cpp +93 -55
- data/vendor/faiss/faiss/utils/simd_impl/rabitq_avx512.cpp +57 -40
- data/vendor/faiss/faiss/utils/simd_impl/{rabitq_avx512_spr.cpp → rabitq_avx512_vpopcnt.cpp} +21 -24
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_dispatch.h +2 -7
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels.h +6 -1
- data/vendor/faiss/faiss/utils/simd_impl/super_kmeans_kernels_sve.cpp +34 -0
- data/vendor/faiss/faiss/utils/simd_levels.cpp +172 -67
- data/vendor/faiss/faiss/utils/simd_levels.h +26 -15
- metadata +6 -5
- data/vendor/faiss/faiss/utils/hamming_distance/hamming_avx512_spr.cpp +0 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a22f4ad8f3c626f1d6571c4cefcb8292965e52eb3b0b77c354f39ed117570c5
|
|
4
|
+
data.tar.gz: b848af534bebc2ecfdfa5fe7eaa270b530d17d5fe5381aea350451aa03c22d9f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4c5083b9733f589fc30c93f429ed4da74fbb4bbdbe2bde17787506cafb178e2715d114e04ed17bd21a1161a096df66a0c502ae6dc245455c1e221737e80a1f3e
|
|
7
|
+
data.tar.gz: 41eb8ce7434c4408fccf238893468e8c808b1961966a9fc495f960d27ff950d5d6a9cafff18a11e14287f5fedc77f83db9118c47c60e06fdc9f86d9987592c7c
|
data/CHANGELOG.md
CHANGED
data/lib/faiss/version.rb
CHANGED
|
@@ -75,6 +75,14 @@ struct ClusteringParameters {
|
|
|
75
75
|
/// so the training process stops only if an error
|
|
76
76
|
/// is unchanged from the previous iteration.
|
|
77
77
|
double early_stop_threshold = 0.0;
|
|
78
|
+
|
|
79
|
+
/// Whether to use the SuperKMeans (super fast k-means) variant instead of
|
|
80
|
+
/// the vanilla Clustering implementation. Only honored by callers that
|
|
81
|
+
/// explicitly support it (e.g. IVF level-1 quantizer training). Cannot be
|
|
82
|
+
/// combined with a user-provided clustering index: SuperKMeans assigns
|
|
83
|
+
/// with its own index, so callers that supply both get an exception rather
|
|
84
|
+
/// than a silent downgrade to vanilla Clustering.
|
|
85
|
+
bool use_super_kmeans = false;
|
|
78
86
|
};
|
|
79
87
|
|
|
80
88
|
struct ClusteringIterationStats {
|
data/vendor/faiss/faiss/Index.h
CHANGED
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
#include <faiss/IndexBinaryFromFloat.h>
|
|
11
11
|
|
|
12
|
+
#include <faiss/MetricType.h>
|
|
12
13
|
#include <faiss/impl/FaissAssert.h>
|
|
13
14
|
#include <faiss/utils/utils.h>
|
|
14
15
|
#include <algorithm>
|
|
16
|
+
#include <cmath>
|
|
15
17
|
#include <memory>
|
|
16
18
|
|
|
17
19
|
namespace faiss {
|
|
@@ -67,8 +69,27 @@ void IndexBinaryFromFloat::search(
|
|
|
67
69
|
binary_to_real(bn * d, x + b * code_size, xf.get());
|
|
68
70
|
|
|
69
71
|
index->search(bn, xf.get(), k, df.get(), labels + b * k);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
// binary_to_real maps bits to {-1, +1}, so the float distance relates
|
|
73
|
+
// to the Hamming distance differently for each metric. In all cases the
|
|
74
|
+
// mapping is monotonic, so the result order needs no adjustment.
|
|
75
|
+
switch (index->metric_type) {
|
|
76
|
+
case METRIC_INNER_PRODUCT:
|
|
77
|
+
for (int i = 0; i < bn * k; ++i) {
|
|
78
|
+
distances[b * k + i] =
|
|
79
|
+
int32_t(std::round((d - df[i]) / 2.0));
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
case METRIC_L1:
|
|
83
|
+
for (int i = 0; i < bn * k; ++i) {
|
|
84
|
+
distances[b * k + i] = int32_t(std::round(df[i] / 2.0));
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
case METRIC_L2:
|
|
88
|
+
default:
|
|
89
|
+
for (int i = 0; i < bn * k; ++i) {
|
|
90
|
+
distances[b * k + i] = int32_t(std::round(df[i] / 4.0));
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
72
93
|
}
|
|
73
94
|
}
|
|
74
95
|
}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
#include <faiss/IndexBinaryHNSW.h>
|
|
9
9
|
|
|
10
|
-
#include <omp.h>
|
|
11
10
|
#include <cassert>
|
|
12
11
|
#include <cmath>
|
|
13
12
|
#include <cstdio>
|
|
@@ -39,140 +38,6 @@
|
|
|
39
38
|
|
|
40
39
|
namespace faiss {
|
|
41
40
|
|
|
42
|
-
/**************************************************************
|
|
43
|
-
* add / search blocks of descriptors
|
|
44
|
-
**************************************************************/
|
|
45
|
-
|
|
46
|
-
namespace {
|
|
47
|
-
|
|
48
|
-
void hnsw_add_vertices(
|
|
49
|
-
IndexBinaryHNSW& index_hnsw,
|
|
50
|
-
size_t n0,
|
|
51
|
-
size_t n,
|
|
52
|
-
const uint8_t* x,
|
|
53
|
-
bool verbose,
|
|
54
|
-
bool preset_levels = false) {
|
|
55
|
-
HNSW& hnsw = index_hnsw.hnsw;
|
|
56
|
-
size_t ntotal = n0 + n;
|
|
57
|
-
double t0 = getmillisecs();
|
|
58
|
-
if (verbose) {
|
|
59
|
-
printf("hnsw_add_vertices: adding %zd elements on top of %zd "
|
|
60
|
-
"(preset_levels=%d)\n",
|
|
61
|
-
n,
|
|
62
|
-
n0,
|
|
63
|
-
int(preset_levels));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
int max_level = hnsw.prepare_level_tab(n, preset_levels);
|
|
67
|
-
|
|
68
|
-
if (verbose) {
|
|
69
|
-
printf(" max_level = %d\n", max_level);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
auto& locks = index_hnsw.locks;
|
|
73
|
-
locks.prepare(ntotal);
|
|
74
|
-
|
|
75
|
-
// add vectors from highest to lowest level
|
|
76
|
-
std::vector<int> hist;
|
|
77
|
-
std::vector<int> order(n);
|
|
78
|
-
|
|
79
|
-
{ // make buckets with vectors of the same level
|
|
80
|
-
|
|
81
|
-
// build histogram
|
|
82
|
-
for (size_t i = 0; i < n; i++) {
|
|
83
|
-
HNSW::storage_idx_t pt_id =
|
|
84
|
-
static_cast<HNSW::storage_idx_t>(i + n0);
|
|
85
|
-
int pt_level = hnsw.levels[pt_id] - 1;
|
|
86
|
-
while (pt_level >= static_cast<int>(hist.size())) {
|
|
87
|
-
hist.push_back(0);
|
|
88
|
-
}
|
|
89
|
-
hist[pt_level]++;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// accumulate
|
|
93
|
-
std::vector<int> offsets(hist.size() + 1, 0);
|
|
94
|
-
for (size_t i = 0; i < hist.size() - 1; i++) {
|
|
95
|
-
offsets[i + 1] = offsets[i] + hist[i];
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// bucket sort
|
|
99
|
-
for (size_t i = 0; i < n; i++) {
|
|
100
|
-
HNSW::storage_idx_t pt_id =
|
|
101
|
-
static_cast<HNSW::storage_idx_t>(i + n0);
|
|
102
|
-
int pt_level = hnsw.levels[pt_id] - 1;
|
|
103
|
-
order[offsets[pt_level]++] = pt_id;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
{ // perform add
|
|
108
|
-
RandomGenerator rng2(789);
|
|
109
|
-
|
|
110
|
-
size_t i1 = static_cast<int>(n);
|
|
111
|
-
|
|
112
|
-
for (int pt_level = static_cast<int>(hist.size()) - 1;
|
|
113
|
-
pt_level >= int(!index_hnsw.init_level0);
|
|
114
|
-
pt_level--) {
|
|
115
|
-
size_t i0 = i1 - hist[pt_level];
|
|
116
|
-
|
|
117
|
-
if (verbose) {
|
|
118
|
-
printf("Adding %zu elements at level %d\n", i1 - i0, pt_level);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// random permutation to get rid of dataset order bias
|
|
122
|
-
for (size_t j = i0; j < i1; j++) {
|
|
123
|
-
std::swap(
|
|
124
|
-
order[j],
|
|
125
|
-
order[j + rng2.rand_int(static_cast<int>(i1 - j))]);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
#pragma omp parallel
|
|
129
|
-
{
|
|
130
|
-
std::unique_ptr<VisitedTable> vt = VisitedTable::create(ntotal);
|
|
131
|
-
|
|
132
|
-
std::unique_ptr<DistanceComputer> dis(
|
|
133
|
-
index_hnsw.get_distance_computer());
|
|
134
|
-
bool do_display = verbose && omp_get_thread_num() == 0;
|
|
135
|
-
size_t prev_display = 0;
|
|
136
|
-
|
|
137
|
-
#pragma omp for schedule(dynamic)
|
|
138
|
-
for (int64_t i = i0; i < i1; i++) {
|
|
139
|
-
HNSW::storage_idx_t pt_id = order[i];
|
|
140
|
-
dis->set_query(
|
|
141
|
-
(float*)(x + (pt_id - n0) * index_hnsw.code_size));
|
|
142
|
-
|
|
143
|
-
hnsw.add_with_locks(
|
|
144
|
-
*dis,
|
|
145
|
-
pt_level,
|
|
146
|
-
pt_id,
|
|
147
|
-
locks,
|
|
148
|
-
*vt,
|
|
149
|
-
index_hnsw.keep_max_size_level0 && (pt_level == 0));
|
|
150
|
-
|
|
151
|
-
if (do_display && i - i0 > prev_display + 10000) {
|
|
152
|
-
prev_display = i - i0;
|
|
153
|
-
printf(" %zu / %zu\r", i - i0, i1 - i0);
|
|
154
|
-
fflush(stdout);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
i1 = i0;
|
|
159
|
-
}
|
|
160
|
-
if (index_hnsw.init_level0) {
|
|
161
|
-
FAISS_ASSERT(i1 == 0);
|
|
162
|
-
} else {
|
|
163
|
-
FAISS_ASSERT((i1 - hist[0]) == 0);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
if (verbose) {
|
|
167
|
-
printf("Done in %.3f ms\n", getmillisecs() - t0);
|
|
168
|
-
}
|
|
169
|
-
if (!index_hnsw.retain_locks) {
|
|
170
|
-
locks.clear();
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
} // anonymous namespace
|
|
175
|
-
|
|
176
41
|
/**************************************************************
|
|
177
42
|
* IndexBinaryHNSW implementation
|
|
178
43
|
**************************************************************/
|
|
@@ -270,18 +135,25 @@ void IndexBinaryHNSW::add(idx_t n, const uint8_t* x) {
|
|
|
270
135
|
storage->add(n, x);
|
|
271
136
|
ntotal = storage->ntotal;
|
|
272
137
|
|
|
273
|
-
|
|
274
|
-
|
|
138
|
+
bool preset_levels = hnsw.levels.size() == static_cast<size_t>(ntotal);
|
|
139
|
+
|
|
140
|
+
hnsw_add_vertices_deterministic(
|
|
141
|
+
hnsw,
|
|
275
142
|
n0,
|
|
276
143
|
n,
|
|
277
|
-
|
|
144
|
+
d,
|
|
145
|
+
init_level0,
|
|
146
|
+
keep_max_size_level0,
|
|
147
|
+
preset_levels,
|
|
278
148
|
verbose,
|
|
279
|
-
|
|
149
|
+
[this] { return get_distance_computer(); },
|
|
150
|
+
[this, x, n0](DistanceComputer& dc, HNSW::storage_idx_t pt_id) {
|
|
151
|
+
dc.set_query((const float*)(x + (pt_id - n0) * code_size));
|
|
152
|
+
});
|
|
280
153
|
}
|
|
281
154
|
|
|
282
155
|
void IndexBinaryHNSW::reset() {
|
|
283
156
|
hnsw.reset();
|
|
284
|
-
locks.clear();
|
|
285
157
|
storage->reset();
|
|
286
158
|
ntotal = 0;
|
|
287
159
|
}
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
|
|
12
12
|
#include <faiss/IndexBinaryFlat.h>
|
|
13
13
|
#include <faiss/impl/HNSW.h>
|
|
14
|
-
#include <faiss/impl/hnsw/LockVector.h>
|
|
15
14
|
#include <faiss/utils/utils.h>
|
|
16
15
|
|
|
17
16
|
namespace faiss {
|
|
@@ -41,11 +40,6 @@ struct IndexBinaryHNSW : IndexBinary {
|
|
|
41
40
|
// used when GpuIndexBinaryCagra::copyFrom(IndexBinaryHNSW*) is called.
|
|
42
41
|
bool keep_max_size_level0 = false;
|
|
43
42
|
|
|
44
|
-
// Per-node locks for HNSW graph construction.
|
|
45
|
-
LockVector locks;
|
|
46
|
-
// locks are freed after each call to add() unless this flag is set.
|
|
47
|
-
bool retain_locks = false;
|
|
48
|
-
|
|
49
43
|
explicit IndexBinaryHNSW();
|
|
50
44
|
explicit IndexBinaryHNSW(int d, int M = 32);
|
|
51
45
|
explicit IndexBinaryHNSW(IndexBinary* storage, int M = 32);
|
|
@@ -192,7 +192,7 @@ void IndexBinaryIVF::reconstruct_n(idx_t i0, idx_t ni, uint8_t* recons) const {
|
|
|
192
192
|
continue;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
uint8_t* reconstructed = recons + (id - i0) *
|
|
195
|
+
uint8_t* reconstructed = recons + (id - i0) * code_size;
|
|
196
196
|
reconstruct_from_offset(list_no, offset, reconstructed);
|
|
197
197
|
}
|
|
198
198
|
}
|
|
@@ -233,10 +233,10 @@ void IndexBinaryIVF::search_and_reconstruct(
|
|
|
233
233
|
for (idx_t j = 0; j < k; ++j) {
|
|
234
234
|
idx_t ij = i * k + j;
|
|
235
235
|
idx_t key = labels[ij];
|
|
236
|
-
uint8_t* reconstructed = recons + ij *
|
|
236
|
+
uint8_t* reconstructed = recons + ij * code_size;
|
|
237
237
|
if (key < 0) {
|
|
238
238
|
// Fill with NaNs
|
|
239
|
-
memset(reconstructed, -1,
|
|
239
|
+
memset(reconstructed, -1, code_size);
|
|
240
240
|
} else {
|
|
241
241
|
int list_no = key >> 32;
|
|
242
242
|
int offset = key & 0xffffffff;
|
|
@@ -348,10 +348,6 @@ void IndexBinaryIVF::replace_invlists(InvertedLists* il, bool own) {
|
|
|
348
348
|
own_invlists = own;
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
-
// IVFBinaryScannerL2, search_knn_hamming_count, BlockSearch,
|
|
352
|
-
// BlockSearchVariableK, search_knn_hamming_per_invlist are now in
|
|
353
|
-
// impl/binary_hamming/IndexBinaryIVF_impl.h (compiled per-ISA)
|
|
354
|
-
|
|
355
351
|
namespace {
|
|
356
352
|
|
|
357
353
|
void search_knn_hamming_heap(
|
|
@@ -461,13 +457,9 @@ void search_knn_hamming_heap(
|
|
|
461
457
|
|
|
462
458
|
} // anonymous namespace
|
|
463
459
|
|
|
464
|
-
// The remaining template code (search_knn_hamming_count,
|
|
465
|
-
// search_knn_hamming_per_invlist, etc.) has been moved to
|
|
466
|
-
// impl/binary_hamming/IndexBinaryIVF_impl.h
|
|
467
|
-
|
|
468
460
|
BinaryInvertedListScanner* IndexBinaryIVF::get_InvertedListScanner(
|
|
469
461
|
bool store_pairs) const {
|
|
470
|
-
return
|
|
462
|
+
return with_simd_level_with_vpopcnt([&]<SIMDLevel SL>() {
|
|
471
463
|
return make_binary_ivf_scanner_fixSL<SL>(code_size, store_pairs);
|
|
472
464
|
});
|
|
473
465
|
}
|
|
@@ -483,7 +475,7 @@ void IndexBinaryIVF::search_preassigned(
|
|
|
483
475
|
bool store_pairs,
|
|
484
476
|
const IVFSearchParameters* params) const {
|
|
485
477
|
if (per_invlist_search) {
|
|
486
|
-
|
|
478
|
+
with_simd_level_with_vpopcnt([&]<SIMDLevel SL>() {
|
|
487
479
|
search_knn_hamming_per_invlist_fixSL<SL>(
|
|
488
480
|
code_size,
|
|
489
481
|
this,
|
|
@@ -501,7 +493,7 @@ void IndexBinaryIVF::search_preassigned(
|
|
|
501
493
|
search_knn_hamming_heap(
|
|
502
494
|
this, n, x, k, cidx, cdis, dis, idx, store_pairs, params);
|
|
503
495
|
} else {
|
|
504
|
-
|
|
496
|
+
with_simd_level_with_vpopcnt([&]<SIMDLevel SL>() {
|
|
505
497
|
search_knn_hamming_count_fixSL<SL>(
|
|
506
498
|
code_size,
|
|
507
499
|
store_pairs,
|
|
@@ -232,7 +232,14 @@ struct BinaryInvertedListScanner {
|
|
|
232
232
|
virtual uint32_t distance_to_code(const uint8_t* code) const = 0;
|
|
233
233
|
|
|
234
234
|
/** compute the distances to codes. (distances, labels) should be
|
|
235
|
-
* organized as a
|
|
235
|
+
* organized as a max-heap: the scan accepts a code whose distance is
|
|
236
|
+
* below distances[0] and replaces the top. A min-heap caller reads its
|
|
237
|
+
* neutral value as a huge unsigned bound and gets wrong results.
|
|
238
|
+
|
|
239
|
+
*
|
|
240
|
+
* The heap top is the only bound. To keep the k nearest codes inside a
|
|
241
|
+
* radius, seed every heap slot with that radius instead of the neutral
|
|
242
|
+
* value; an unfilled slot keeps its label of -1.
|
|
236
243
|
*
|
|
237
244
|
* @param n number of codes to scan
|
|
238
245
|
* @param codes codes to scan (n * code_size)
|
|
@@ -270,9 +270,11 @@ struct FlatIPDis : FlatCodesDistanceComputer {
|
|
|
270
270
|
FlatCodesDistanceComputer* IndexFlat::get_FlatCodesDistanceComputer() const {
|
|
271
271
|
FlatCodesDistanceComputer* dc = nullptr;
|
|
272
272
|
if (metric_type == METRIC_L2) {
|
|
273
|
-
|
|
273
|
+
with_simd_level_with_sve(
|
|
274
|
+
[&]<SIMDLevel SL>() { dc = new FlatL2Dis<SL>(*this); });
|
|
274
275
|
} else if (metric_type == METRIC_INNER_PRODUCT) {
|
|
275
|
-
|
|
276
|
+
with_simd_level_with_sve(
|
|
277
|
+
[&]<SIMDLevel SL>() { dc = new FlatIPDis<SL>(*this); });
|
|
276
278
|
} else {
|
|
277
279
|
dc = get_extra_distance_computer(d, metric_type, metric_arg, get_xb());
|
|
278
280
|
}
|
|
@@ -404,7 +406,7 @@ FlatCodesDistanceComputer* IndexFlatL2::get_FlatCodesDistanceComputer() const {
|
|
|
404
406
|
if (metric_type == METRIC_L2) {
|
|
405
407
|
if (!cached_l2norms.empty()) {
|
|
406
408
|
FlatCodesDistanceComputer* dc = nullptr;
|
|
407
|
-
|
|
409
|
+
with_simd_level_with_sve([&]<SIMDLevel SL>() {
|
|
408
410
|
dc = new FlatL2WithNormsDis<SL>(*this);
|
|
409
411
|
});
|
|
410
412
|
return dc;
|
|
@@ -704,10 +706,12 @@ void IndexFlatPanorama::reset() {
|
|
|
704
706
|
}
|
|
705
707
|
|
|
706
708
|
void IndexFlatPanorama::reconstruct(idx_t key, float* recons) const {
|
|
709
|
+
FAISS_THROW_IF_NOT(key >= 0 && key < ntotal);
|
|
707
710
|
pano.reconstruct(key, recons, codes.data());
|
|
708
711
|
}
|
|
709
712
|
|
|
710
713
|
void IndexFlatPanorama::reconstruct_n(idx_t i, idx_t n, float* recons) const {
|
|
714
|
+
FAISS_THROW_IF_NOT(i >= 0 && i <= ntotal && n >= 0 && n <= ntotal - i);
|
|
711
715
|
Index::reconstruct_n(i, n, recons);
|
|
712
716
|
}
|
|
713
717
|
|
|
@@ -784,7 +788,7 @@ void IndexFlatPanorama::search_subset(
|
|
|
784
788
|
idx_t k,
|
|
785
789
|
float* distances,
|
|
786
790
|
idx_t* labels) const {
|
|
787
|
-
|
|
791
|
+
with_simd_level_with_sve([&]<SIMDLevel SL>() {
|
|
788
792
|
with_metric_type(metric_type, [&]<MetricType M>() {
|
|
789
793
|
constexpr bool is_sim = is_similarity_metric(M);
|
|
790
794
|
using C = std::conditional_t<
|
|
@@ -176,7 +176,7 @@ struct IndexFlatL2Panorama : IndexFlatPanorama {
|
|
|
176
176
|
explicit IndexFlatL2Panorama(
|
|
177
177
|
idx_t d_in,
|
|
178
178
|
size_t n_levels_in,
|
|
179
|
-
size_t batch_size_in =
|
|
179
|
+
size_t batch_size_in = Panorama::kDefaultBatchSize)
|
|
180
180
|
: IndexFlatPanorama(d_in, METRIC_L2, n_levels_in, batch_size_in) {}
|
|
181
181
|
};
|
|
182
182
|
|
|
@@ -189,7 +189,7 @@ struct IndexFlatIPPanorama : IndexFlatPanorama {
|
|
|
189
189
|
explicit IndexFlatIPPanorama(
|
|
190
190
|
idx_t d_in,
|
|
191
191
|
size_t n_levels_in,
|
|
192
|
-
size_t batch_size_in =
|
|
192
|
+
size_t batch_size_in = Panorama::kDefaultBatchSize)
|
|
193
193
|
: IndexFlatPanorama(
|
|
194
194
|
d_in,
|
|
195
195
|
METRIC_INNER_PRODUCT,
|