Skip to content

Commit b801218

Browse files
authored
IVF-PQ tests: fix segfault when accessing empty lists (#838)
Check if the `index.lists()[label]` is not an empty shared pointer before accessing its content in tests. If the list size is zero, the list shared pointer can be `.reset()` during deserialization/resizing. Hence IVF-Flat and IVF-PQ can sometimes have empty shared pointers in their `.lists()` members. In case of IVF-PQ, we've had a piece of tests where this wasn't checked before accessing. As a result, we have been observing occasional CI failures with segfaults - when the IVF-PQ index was very unbalanced, i.e. had empty lists. So far, the affected test is the only place I could identify where the access to the list pointer is unprotected (either via explicit check or by the invariant list_size > 0). Authors: - Artem M. Chirkin (https://github.com/achirkin) - Corey J. Nolet (https://github.com/cjnolet) Approvers: - Bradley Dice (https://github.com/bdice) - Tamas Bela Feher (https://github.com/tfeher) URL: #838
1 parent d2adc6f commit b801218

1 file changed

Lines changed: 5 additions & 3 deletions

File tree

cpp/tests/neighbors/ann_ivf_pq.cuh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,11 @@ class ivf_pq_test : public ::testing::TestWithParam<ivf_pq_inputs> {
283283
// the original data cannot be reconstructed since the dataset was normalized
284284
if (index.metric() == cuvs::distance::DistanceType::CosineExpanded) { return; }
285285
auto& rec_list = index.lists()[label];
286-
auto dim = index.dim();
287-
n_take = std::min<uint32_t>(n_take, rec_list->size.load());
288-
n_skip = std::min<uint32_t>(n_skip, rec_list->size.load() - n_take);
286+
// If the data is unbalanced the list might be empty, which is actually nullptr
287+
if (!rec_list) { return; }
288+
auto dim = index.dim();
289+
n_take = std::min<uint32_t>(n_take, rec_list->size.load());
290+
n_skip = std::min<uint32_t>(n_skip, rec_list->size.load() - n_take);
289291

290292
if (n_take == 0) { return; }
291293

0 commit comments

Comments
 (0)