12 #include "IVFBase.cuh"
13 #include "../GpuResources.h"
14 #include "FlatIndex.cuh"
15 #include "InvertedListAppend.cuh"
16 #include "RemapIndices.h"
17 #include "../utils/DeviceDefs.cuh"
18 #include "../utils/DeviceUtils.h"
19 #include "../utils/HostTensor.cuh"
21 #include <thrust/host_vector.h>
22 #include <unordered_map>
24 namespace faiss {
namespace gpu {
29 IndicesOptions indicesOptions) :
30 resources_(resources),
31 quantizer_(quantizer),
32 bytesPerVector_(bytesPerVector),
33 indicesOptions_(indicesOptions),
34 dim_(quantizer->getDim()),
35 numLists_(quantizer->getSize()),
46 if (vecsPerList < 1) {
50 auto stream =
resources_->getDefaultStreamCurrentDevice();
54 list->reserve(bytesPerDataList, stream);
60 size_t bytesPerIndexList = vecsPerList *
63 for (
auto& list : deviceListIndices_) {
64 list->reserve(bytesPerIndexList, stream);
76 deviceListIndices_.clear();
85 deviceListIndices_.emplace_back(
110 auto stream =
resources_->getDefaultStreamCurrentDevice();
112 size_t totalReclaimed = 0;
116 totalReclaimed += data->reclaim(exact, stream);
121 for (
int i = 0; i < deviceListIndices_.size(); ++i) {
122 auto& indices = deviceListIndices_[i];
123 totalReclaimed += indices->reclaim(exact, stream);
132 return totalReclaimed;
147 cudaStream_t stream) {
148 auto& mem =
resources_->getMemoryManagerCurrentDevice();
151 hostListsToUpdate({(int) listIds.size()});
153 hostNewListLength({(int) listIds.size()});
155 hostNewDataPointers({(int) listIds.size()});
157 hostNewIndexPointers({(int) listIds.size()});
159 for (
int i = 0; i < listIds.size(); ++i) {
160 auto listId = listIds[i];
162 auto& indices = deviceListIndices_[listId];
164 hostListsToUpdate[i] = listId;
166 hostNewDataPointers[i] = data->data();
167 hostNewIndexPointers[i] = indices->data();
172 mem, hostListsToUpdate, stream);
174 mem, hostNewListLength, stream);
176 mem, hostNewDataPointers, stream);
178 mem, hostNewIndexPointers, stream);
182 runUpdateListPointers(listsToUpdate,
209 FAISS_ASSERT(listId < deviceListIndices_.size());
211 auto intInd = deviceListIndices_[listId]->copyToHost<
int>(
214 std::vector<long> out(intInd.size());
215 for (
size_t i = 0; i < intInd.size(); ++i) {
216 out[i] = (long) intInd[i];
221 FAISS_ASSERT(listId < deviceListIndices_.size());
223 return deviceListIndices_[listId]->copyToHost<
long>(
230 FAISS_ASSERT(userIds.size() ==
238 return std::vector<long>();
246 auto stream =
resources_->getDefaultStreamCurrentDevice();
248 auto& listIndices = deviceListIndices_[listId];
249 auto prevIndicesData = listIndices->data();
253 std::vector<int> indices32(numVecs);
254 for (
size_t i = 0; i < numVecs; ++i) {
255 auto ind = indices[i];
256 FAISS_ASSERT(ind <= (
long) std::numeric_limits<int>::max());
257 indices32[i] = (int) ind;
260 listIndices->append((
unsigned char*) indices32.data(),
261 numVecs *
sizeof(int),
265 listIndices->append((
unsigned char*) indices,
266 numVecs *
sizeof(
long),
274 userIndices.insert(userIndices.begin(), indices, indices + numVecs);
280 if (prevIndicesData != listIndices->data()) {
const int numLists_
Number of inverted lists we maintain.
int maxListLength_
Maximum list length seen.
std::vector< std::vector< long > > listOffsetToUserIndex_
Holder of GPU resources for a particular flat index.
int getDim() const
Return the number of dimensions we are indexing.
int getListLength(int listId) const
void reserveMemory(size_t numVecs)
Reserve GPU memory in our inverted lists for this number of vectors.
size_t reclaimMemory_(bool exact)
thrust::device_vector< int > deviceListLengths_
thrust::device_vector< void * > deviceListIndexPointers_
IVFBase(GpuResources *resources, FlatIndex *quantizer, int bytesPerVector, IndicesOptions indicesOptions)
thrust::device_vector< void * > deviceListDataPointers_
GpuResources * resources_
Collection of GPU resources that we use.
const int bytesPerVector_
Number of bytes per vector in the list.
void updateDeviceListInfo_(cudaStream_t stream)
Update all device-side list pointer and size information.
std::vector< long > getListIndices(int listId) const
Return the list indices of a particular list back to the CPU.
const IndicesOptions indicesOptions_
How are user indices stored on the GPU?
std::vector< std::unique_ptr< DeviceVector< unsigned char > > > deviceListData_
const int dim_
Expected dimensionality of the vectors.
void addIndicesFromCpu_(int listId, const long *indices, size_t numVecs)
Shared function to copy indices from CPU to GPU.
size_t getNumLists() const
Returns the number of inverted lists.