Skip to content

Commit e322d71

Browse files
authored
Initial work to get IVF PQ working like Vamana does (#390)
1 parent 5ee2aaa commit e322d71

17 files changed

+2885
-112
lines changed

src/include/api/ivf_pq_index.h

Lines changed: 615 additions & 0 deletions
Large diffs are not rendered by default.

src/include/api/vamana_index.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ class IndexVamana {
185185
// Create a new index. Note that we may have already loaded an existing
186186
// index by URI. In that case, we have updated our local state (i.e.
187187
// l_build_, r_max_degree_, b_backtrack_), but we should also use the
188-
// timestamp from that already loaded index..
188+
// timestamp from that already loaded index.
189189
index_ = dispatch_table.at(type)(
190190
training_set.num_vectors(),
191191
l_build_,

src/include/detail/flat/qv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,8 @@ auto qv_partition(
497497
std::vector<id_type> top_k(num_vectors(q));
498498

499499
auto par = stdx::execution::indexed_parallel_policy{(size_t)nthreads};
500+
// For each query vector, find the closest vector in the database (i.e. in
501+
// centroids).
500502
stdx::range_for_each(
501503
std::move(par), q, [&, size_db](auto&& qvec, auto&& n = 0, auto&& j = 0) {
502504
score_type min_score = std::numeric_limits<score_type>::max();

src/include/detail/ivf/partition.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,12 @@ auto partition_ivf_flat_index(
8989
Distance distance = Distance{}) {
9090
scoped_timer _{tdb_func__};
9191

92-
assert(::num_vectors(centroids) >= nprobe);
92+
if (::num_vectors(centroids) < nprobe) {
93+
throw std::invalid_argument(
94+
"nprobe (" + std::to_string(nprobe) +
95+
") must be less than the number of centroids (" +
96+
std::to_string(::num_vectors(centroids)) + ")");
97+
}
9398

9499
size_t num_queries = num_vectors(query);
95100

src/include/detail/linalg/partitioned_matrix.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,17 +155,11 @@ class PartitionedMatrix : public Matrix<T, LayoutPolicy, I> {
155155
, part_index_(num_parts + 1)
156156
, num_vectors_{::num_vectors(training_set)}
157157
, num_parts_{num_parts} {
158-
if (num_vectors_ == 0) {
159-
throw std::invalid_argument("training_set cannot be empty.");
160-
}
161158
if (size(part_labels) != ::num_vectors(training_set)) {
162159
throw std::invalid_argument(
163160
"The number of part_labels must equal the number of vectors in the "
164161
"training_set.");
165162
}
166-
if (num_parts <= 0) {
167-
throw std::invalid_argument("num_parts should be greater than 0.");
168-
}
169163

170164
auto degrees = std::vector<size_t>(num_parts);
171165

@@ -180,7 +174,11 @@ class PartitionedMatrix : public Matrix<T, LayoutPolicy, I> {
180174
size_t bin = part_labels[i];
181175
size_t ibin = part_index_[bin];
182176

183-
ids_[ibin] = i;
177+
if constexpr (feature_vector_array_with_ids<F>) {
178+
ids_[ibin] = training_set.id(i);
179+
} else {
180+
ids_[ibin] = i;
181+
}
184182

185183
assert(ibin < this->num_cols());
186184
for (size_t j = 0; j < dimensions(training_set); ++j) {

src/include/index/flat_pq_index.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,11 @@ class flat_pq_index {
237237

238238
template <class SubDistance = cached_sub_sum_of_squares_distance>
239239
auto add(const ColMajorMatrix<feature_type>& feature_vectors) {
240+
// These will be encoded. We will still have the same number of vectors, but
241+
// now each will have num_subspaces_ dimensions instead of the original
242+
// dimensions_. This is because we will chunk up the original vector into
243+
// num_subspaces_ chunks and then for each chunk the vector will get an ID
244+
// which maps to a set of numbers which are stored in centroids_.
240245
pq_vectors_ =
241246
ColMajorMatrix<code_type>(num_subspaces_, num_vectors(feature_vectors));
242247

src/include/index/index_defs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ enum class IndexKind { FlatL2, IVFFlat, Vamana, IVFPQ };
5555
return index_kind_strings[static_cast<int>(kind)];
5656
}
5757

58+
enum class QueryType { FiniteRAM, InfiniteRAM };
59+
5860
/******************************************************************************
5961
* Static info for arrays associated with an index group
6062
******************************************************************************/

src/include/index/ivf_pq_group.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,25 @@ class ivf_pq_group : public base_index_group<index_type> {
129129
}
130130
}
131131

132+
void clear_history_impl(uint64_t timestamp) {
133+
tiledb::Array::delete_fragments(
134+
cached_ctx_, cluster_centroids_uri(), 0, timestamp);
135+
tiledb::Array::delete_fragments(
136+
cached_ctx_, flat_ivf_centroids_uri(), 0, timestamp);
137+
tiledb::Array::delete_fragments(
138+
cached_ctx_, pq_ivf_centroids_uri(), 0, timestamp);
139+
tiledb::Array::delete_fragments(cached_ctx_, ivf_index_uri(), 0, timestamp);
140+
tiledb::Array::delete_fragments(cached_ctx_, ivf_ids_uri(), 0, timestamp);
141+
tiledb::Array::delete_fragments(
142+
cached_ctx_, pq_ivf_vectors_uri(), 0, timestamp);
143+
for (size_t i = 0; i < this->get_num_subspaces(); ++i) {
144+
std::string this_table_uri =
145+
distance_tables_uri() + "_" + std::to_string(i);
146+
tiledb::Array::delete_fragments(
147+
cached_ctx_, this_table_uri, 0, timestamp);
148+
}
149+
}
150+
132151
/*****************************************************************************
133152
* Partitioning / repartitioning history information
134153
****************************************************************************/
@@ -269,9 +288,9 @@ class ivf_pq_group : public base_index_group<index_type> {
269288
type_to_string_v<typename index_type::indices_type>;
270289

271290
// Initialize IVF related metadata
272-
metadata_.ingestion_timestamps_ = {0};
273-
metadata_.base_sizes_ = {0};
274-
metadata_.partition_history_ = {0};
291+
metadata_.ingestion_timestamps_ = {};
292+
metadata_.base_sizes_ = {};
293+
metadata_.partition_history_ = {};
275294
metadata_.temp_size_ = 0;
276295
metadata_.dimensions_ = this->get_dimensions();
277296

0 commit comments

Comments
 (0)