Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python: GpuIndexIVFFlat with externally provided GpuIndexFlat quantizer crashes if quantizer goes out of scope #3993

Open
2 of 4 tasks
gabuzi opened this issue Oct 26, 2024 · 1 comment

Comments

@gabuzi
Copy link

gabuzi commented Oct 26, 2024

Summary

While experimenting with IVFFlat indexes in Python, I noticed what I believe to be a bug in the GPU implementation.
In short, if you pass an index object as the quantizer in the constructor call to GpuIndexIVFFlat and that
object goes out of scope or is manually deld, Faiss crashes (SIGSEGV) when trying to use the index.

The CPU implementation does not show this behavior (works despite coarse quantizer being deld).

Platform

OS: Ubuntu 22.04

Faiss version: 1.9.0, but applies to a custom fork based off 1.7.4 as well where I have discovered it, so the issue is probably older.

Installed from: anaconda

Faiss compilation options:

Running on:

  • CPU
  • GPU

Interface:

  • C++
  • Python

Reproduction instructions

CPU case that works robustly

import numpy as np
import faiss

dim = 10
nv = 1000

db = np.random.rand(nv, dim)

idx_coarse = faiss.IndexFlat(dim, faiss.METRIC_L2)

idx = faiss.IndexIVFFlat(idx_coarse, dim, faiss.METRIC_L2)

del(idx_coarse)  # delete the coarse quantizer

idx.train(db)  # no problem

# del(idx_coarse)  # if we do it here, also no problem

idx.add(db)

# del(idx_coarse)  # if we do it here, also no problem

idx.search(db, 1)

On the GPU, stuff breaks:

import numpy as np
import faiss

dim = 10
nv = 1000

db = np.random.rand(nv, dim)

res = faiss.StandardGpuResources()

idx_coarse = faiss.GpuIndexFlat(res, dim, faiss.METRIC_L2)

idx = faiss.GpuIndexIVFFlat(res, idx_coarse, dim, faiss.METRIC_L2)

del(idx_coarse)  # deletion site (1)

idx.train(db)  # BOOM(1) assertion error. Consistency check failure that quantizer's `d` != index's `d` due to being undefined values in quantizer's d field.

# del(idx_coarse)  # if we delete here (2)

idx.add(db)  # BOOM (2) SIGSEGV

del(idx_coarse)  # if we delete here (3)

# idx.search(db, 1)  # BOOM (3) SIGSEGV
@mdouze
Copy link
Contributor

mdouze commented Nov 4, 2024

Seems plausible, GpuIndexIVFFlat does not add the ref in the constructor as done for the CPU indexes

https://github.com/facebookresearch/faiss/blob/main/faiss/python/__init__.py#L162

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants