12 #include "GpuIndexIVFFlat.h"
13 #include "../IndexFlat.h"
14 #include "../IndexIVF.h"
15 #include "GpuIndexFlat.h"
16 #include "GpuResources.h"
17 #include "impl/IVFFlat.cuh"
18 #include "utils/CopyUtils.cuh"
19 #include "utils/DeviceUtils.h"
20 #include "utils/Float16.cuh"
24 namespace faiss {
namespace gpu {
28 bool useFloat16CoarseQuantizer,
29 bool useFloat16IVFStorage,
32 IndicesOptions indicesOptions,
37 useFloat16CoarseQuantizer,
41 useFloat16IVFStorage_(useFloat16IVFStorage),
42 reserveMemoryVecs_(0),
49 #ifndef FAISS_USE_FLOAT16
50 FAISS_ASSERT(!useFloat16IVFStorage_,
51 "float16 unsupported; need CUDA SDK >= 7.5");
61 bool useFloat16IVFStorage,
64 IndicesOptions indicesOptions,
66 GpuIndexIVF(resources, device, indicesOptions, dims,
67 metric, nlist, quantizer),
68 useFloat16IVFStorage_(useFloat16IVFStorage),
69 reserveMemoryVecs_(0),
76 #ifndef FAISS_USE_FLOAT16
77 FAISS_ASSERT(!useFloat16IVFStorage_,
78 "float16 unsupported; need CUDA SDK >= 7.5");
85 useFloat16IVFStorage_,
90 GpuIndexIVFFlat::~GpuIndexIVFFlat() {
96 reserveMemoryVecs_ = numVecs;
124 useFloat16IVFStorage_,
127 FAISS_ASSERT(index->
vecs.size() == index->
ids.size());
128 for (
size_t i = 0; i < index->
vecs.size(); ++i) {
129 auto& vecs = index->
vecs[i];
130 auto& ids = index->
ids[i];
132 FAISS_ASSERT(vecs.size() % this->
d == 0);
133 auto numVecs = vecs.size() / this->
d;
134 FAISS_ASSERT(numVecs == ids.size());
155 for (
int i = 0; i <
nlist_; ++i) {
181 FAISS_ASSERT(this->
ntotal == 0);
192 FAISS_ASSERT(index_);
196 FAISS_ASSERT(!index_);
198 trainQuantizer_(n, x);
204 useFloat16IVFStorage_,
206 if (reserveMemoryVecs_) {
218 FAISS_ASSERT(index_);
221 auto stream =
resources_->getDefaultStreamCurrentDevice();
226 const_cast<float*
>(x),
228 {(int) n, index_->
getDim()});
230 static_assert(
sizeof(
long) ==
sizeof(
Index::idx_t),
"size mismatch");
234 const_cast<long*
>(xids),
254 FAISS_ASSERT(index_);
257 auto stream = resources_->getDefaultStream(device_);
264 const_cast<float*
>(x),
280 index_->
query(devX,
nprobe_, k, devDistances, devLabels);
283 fromDevice<float, 2>(devDistances, distances, stream);
284 fromDevice<faiss::Index::idx_t, 2>(devLabels, labels, stream);
288 GpuIndexIVFFlat::set_typename() {
289 this->index_typename =
"GpuIndexIVFFlat";
int getDim() const
Return the number of dimensions we are indexing.
FlatIndex * getGpuData()
For internal access.
void copyFrom(const faiss::IndexIVFFlat *index)
void reserveMemory(size_t numVecs)
Reserve GPU memory in our inverted lists for this number of vectors.
void train(Index::idx_t n, const float *x) override
int device_
The GPU device we are resident on.
std::vector< std::vector< long > > ids
Inverted lists for indexes.
int classifyAndAddVectors(Tensor< float, 2, true > &vecs, Tensor< long, 1, true > &indices)
void copyTo(faiss::IndexIVFFlat *index) const
int nprobe_
Number of inverted list probes per query.
const IndicesOptions indicesOptions_
How should indices be stored on the GPU?
void reserveMemory(size_t numVecs)
Reserve GPU memory in our inverted lists for this number of vectors.
GpuResources * resources_
Manages streans, cuBLAS handles and scratch memory for devices.
void copyTo(faiss::IndexIVF *index) const
Copy what we have to the CPU equivalent.
long idx_t
all indices are this type
int nlist_
Number of inverted lists that we manage.
idx_t ntotal
total nb of indexed vectors
void add_with_ids(Index::idx_t n, const float *x, const Index::idx_t *xids) override
void addCodeVectorsFromCpu(int listId, const float *vecs, const long *indices, size_t numVecs)
GpuIndexFlat * quantizer_
Quantizer for inverted lists.
void query(Tensor< float, 2, true > &queries, int nprobe, int k, Tensor< float, 2, true > &outDistances, Tensor< long, 2, true > &outIndices)
std::vector< float > getListVectors(int listId) const
Return the vectors of a particular list back to the CPU.
MetricType metric_type
type of metric this index uses for search
GpuIndexIVFFlat(GpuResources *resources, int device, bool useFloat16CoarseQuantizer, bool useFloat16IVFStorage, int dims, int nlist, IndicesOptions indicesOptions, faiss::MetricType metric)
std::vector< long > getListIndices(int listId) const
Return the list indices of a particular list back to the CPU.
void copyFrom(const faiss::IndexIVF *index)
Copy what we need from the CPU equivalent.
bool is_trained
set if the Index does not require training, or if training is done already
void reset() override
removes all elements from the database.
void search(faiss::Index::idx_t n, const float *x, faiss::Index::idx_t k, float *distances, faiss::Index::idx_t *labels) const override
MetricType
Some algorithms support both an inner product vetsion and a L2 search version.
std::vector< std::vector< float > > vecs