10 #include "IVFBase.cuh"
11 #include "../GpuResources.h"
12 #include "FlatIndex.cuh"
13 #include "InvertedListAppend.cuh"
14 #include "RemapIndices.h"
15 #include "../utils/DeviceDefs.cuh"
16 #include "../utils/DeviceUtils.h"
17 #include "../utils/HostTensor.cuh"
19 #include <thrust/host_vector.h>
20 #include <unordered_map>
22 namespace faiss {
namespace gpu {
27 IndicesOptions indicesOptions,
29 resources_(resources),
30 quantizer_(quantizer),
31 bytesPerVector_(bytesPerVector),
32 indicesOptions_(indicesOptions),
34 dim_(quantizer->getDim()),
35 numLists_(quantizer->getSize()),
46 if (vecsPerList < 1) {
54 list->reserve(bytesPerDataList, stream);
60 size_t bytesPerIndexList = vecsPerList *
63 for (
auto& list : deviceListIndices_) {
64 list->reserve(bytesPerIndexList, stream);
76 deviceListIndices_.clear();
86 deviceListIndices_.emplace_back(
113 size_t totalReclaimed = 0;
117 totalReclaimed += data->reclaim(exact, stream);
122 for (
int i = 0; i < deviceListIndices_.size(); ++i) {
123 auto& indices = deviceListIndices_[i];
124 totalReclaimed += indices->reclaim(exact, stream);
133 return totalReclaimed;
148 cudaStream_t stream) {
152 hostListsToUpdate({(int) listIds.size()});
154 hostNewListLength({(int) listIds.size()});
156 hostNewDataPointers({(int) listIds.size()});
158 hostNewIndexPointers({(int) listIds.size()});
160 for (
int i = 0; i < listIds.size(); ++i) {
161 auto listId = listIds[i];
163 auto& indices = deviceListIndices_[listId];
165 hostListsToUpdate[i] = listId;
167 hostNewDataPointers[i] = data->data();
168 hostNewIndexPointers[i] = indices->data();
173 mem, hostListsToUpdate, stream);
175 mem, hostNewListLength, stream);
177 mem, hostNewDataPointers, stream);
179 mem, hostNewIndexPointers, stream);
183 runUpdateListPointers(listsToUpdate,
210 FAISS_ASSERT(listId < deviceListIndices_.size());
212 auto intInd = deviceListIndices_[listId]->copyToHost<
int>(
215 std::vector<long> out(intInd.size());
216 for (
size_t i = 0; i < intInd.size(); ++i) {
217 out[i] = (long) intInd[i];
222 FAISS_ASSERT(listId < deviceListIndices_.size());
224 return deviceListIndices_[listId]->copyToHost<
long>(
231 FAISS_ASSERT(userIds.size() ==
239 return std::vector<long>();
249 auto& listIndices = deviceListIndices_[listId];
250 auto prevIndicesData = listIndices->data();
254 std::vector<int> indices32(numVecs);
255 for (
size_t i = 0; i < numVecs; ++i) {
256 auto ind = indices[i];
257 FAISS_ASSERT(ind <= (
long) std::numeric_limits<int>::max());
258 indices32[i] = (int) ind;
261 listIndices->append((
unsigned char*) indices32.data(),
262 numVecs *
sizeof(int),
266 listIndices->append((
unsigned char*) indices,
267 numVecs *
sizeof(
long),
275 userIndices.insert(userIndices.begin(), indices, indices + numVecs);
281 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.