11 #include "IVFBase.cuh"
12 #include "../GpuResources.h"
13 #include "FlatIndex.cuh"
14 #include "InvertedListAppend.cuh"
15 #include "RemapIndices.h"
16 #include "../utils/DeviceDefs.cuh"
17 #include "../utils/DeviceUtils.h"
18 #include "../utils/HostTensor.cuh"
20 #include <thrust/host_vector.h>
21 #include <unordered_map>
23 namespace faiss {
namespace gpu {
28 IndicesOptions indicesOptions,
30 resources_(resources),
31 quantizer_(quantizer),
32 bytesPerVector_(bytesPerVector),
33 indicesOptions_(indicesOptions),
35 dim_(quantizer->getDim()),
36 numLists_(quantizer->getSize()),
47 if (vecsPerList < 1) {
55 list->reserve(bytesPerDataList, stream);
61 size_t bytesPerIndexList = vecsPerList *
64 for (
auto& list : deviceListIndices_) {
65 list->reserve(bytesPerIndexList, stream);
77 deviceListIndices_.clear();
87 deviceListIndices_.emplace_back(
114 size_t totalReclaimed = 0;
118 totalReclaimed += data->reclaim(exact, stream);
123 for (
int i = 0; i < deviceListIndices_.size(); ++i) {
124 auto& indices = deviceListIndices_[i];
125 totalReclaimed += indices->reclaim(exact, stream);
134 return totalReclaimed;
149 cudaStream_t stream) {
153 hostListsToUpdate({(int) listIds.size()});
155 hostNewListLength({(int) listIds.size()});
157 hostNewDataPointers({(int) listIds.size()});
159 hostNewIndexPointers({(int) listIds.size()});
161 for (
int i = 0; i < listIds.size(); ++i) {
162 auto listId = listIds[i];
164 auto& indices = deviceListIndices_[listId];
166 hostListsToUpdate[i] = listId;
168 hostNewDataPointers[i] = data->data();
169 hostNewIndexPointers[i] = indices->data();
174 mem, hostListsToUpdate, stream);
176 mem, hostNewListLength, stream);
178 mem, hostNewDataPointers, stream);
180 mem, hostNewIndexPointers, stream);
184 runUpdateListPointers(listsToUpdate,
211 FAISS_ASSERT(listId < deviceListIndices_.size());
213 auto intInd = deviceListIndices_[listId]->copyToHost<
int>(
216 std::vector<long> out(intInd.size());
217 for (
size_t i = 0; i < intInd.size(); ++i) {
218 out[i] = (long) intInd[i];
223 FAISS_ASSERT(listId < deviceListIndices_.size());
225 return deviceListIndices_[listId]->copyToHost<
long>(
232 FAISS_ASSERT(userIds.size() ==
240 return std::vector<long>();
250 auto& listIndices = deviceListIndices_[listId];
251 auto prevIndicesData = listIndices->data();
255 std::vector<int> indices32(numVecs);
256 for (
size_t i = 0; i < numVecs; ++i) {
257 auto ind = indices[i];
258 FAISS_ASSERT(ind <= (
long) std::numeric_limits<int>::max());
259 indices32[i] = (int) ind;
262 listIndices->append((
unsigned char*) indices32.data(),
263 numVecs *
sizeof(int),
267 listIndices->append((
unsigned char*) indices,
268 numVecs *
sizeof(
long),
276 userIndices.insert(userIndices.begin(), indices, indices + numVecs);
282 if (prevIndicesData != listIndices->data()) {
const int numLists_
Number of inverted lists we maintain.
int maxListLength_
Maximum list length seen.
cudaStream_t getDefaultStreamCurrentDevice()
Calls getDefaultStream with the current device.
IVFBase(GpuResources *resources, FlatIndex *quantizer, int bytesPerVector, IndicesOptions indicesOptions, MemorySpace space)
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_
DeviceMemory & getMemoryManagerCurrentDevice()
Calls getMemoryManager for the current device.
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?
const MemorySpace space_
What memory space our inverted list storage is in.
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.