9 #include "GpuIndexBinaryFlat.h"
11 #include "GpuResources.h"
12 #include "impl/BinaryFlatIndex.cuh"
13 #include "utils/ConversionOperators.cuh"
14 #include "utils/CopyUtils.cuh"
15 #include "utils/DeviceUtils.h"
17 #include <thrust/execution_policy.h>
18 #include <thrust/transform.h>
20 namespace faiss {
namespace gpu {
23 constexpr
size_t kMinPageSize = (size_t) 256 * 1024 * 1024;
29 resources_(resources),
30 config_(std::move(config)),
32 FAISS_THROW_IF_NOT_FMT(this->
d % 8 == 0,
33 "vector dimension (number of bits) "
34 "must be divisible by 8 (passed %d)",
48 resources_(resources),
49 config_(std::move(config)),
51 FAISS_THROW_IF_NOT_FMT(this->
d % 8 == 0,
52 "vector dimension (number of bits) "
53 "must be divisible by 8 (passed %d)",
66 GpuIndexBinaryFlat::~GpuIndexBinaryFlat() {
77 FAISS_THROW_IF_NOT_FMT(index->
ntotal <=
79 "GPU index only supports up to %zu indices; "
80 "attempting to copy CPU index with %zu parameters",
81 (
size_t) std::numeric_limits<int>::max(),
107 index->
xb.resize(this->
ntotal * (this->
d / 8));
127 FAISS_THROW_IF_NOT_FMT(this->
ntotal + n <=
129 "GPU index only supports up to %zu indices",
130 (
size_t) std::numeric_limits<int>::max());
132 data_->
add((
const unsigned char*) x,
158 FAISS_THROW_IF_NOT_FMT(n <=
160 "GPU index only supports up to %zu indices",
161 (
size_t) std::numeric_limits<int>::max());
162 FAISS_THROW_IF_NOT_FMT(k <= 1024,
163 "GPU only supports k <= 1024 (requested %d)",
175 auto outDistances = toDevice<int32_t, 2>(
resources_,
183 resources_->getMemoryManagerCurrentDevice(),
184 {(int) n, (
int) k}, stream);
186 bool usePaged =
false;
188 if (getDeviceForAddress(x) == -1) {
195 size_t dataSize = (size_t) n * (this->
d / 8) *
sizeof(uint8_t);
197 if (dataSize >= kMinPageSize) {
200 outIntIndices.data());
206 searchNonPaged_(n, x, k,
208 outIntIndices.data());
212 auto outIndices = toDevice<faiss::Index::idx_t, 2>(
resources_,
219 thrust::transform(thrust::cuda::par.on(stream),
220 outIntIndices.data(),
226 fromDevice<int32_t, 2>(outDistances, distances, stream);
227 fromDevice<faiss::Index::idx_t, 2>(outIndices, labels, stream);
231 GpuIndexBinaryFlat::searchNonPaged_(
int n,
234 int32_t* outDistancesData,
235 int* outIndicesData)
const {
237 Tensor<int, 2, true> outIndices(outIndicesData, {n, k});
245 const_cast<uint8_t*
>(x),
247 {n, (int) (this->
d / 8)});
249 data_->query(vecs, k, outDistances, outIndices);
256 int32_t* outDistancesData,
257 int* outIndicesData)
const {
261 auto vectorSize =
sizeof(uint8_t) * (this->
d / 8);
264 int batchSize = utils::nextHighestPowerOf2(
265 (
int) ((
size_t) kMinPageSize / vectorSize));
267 for (
int cur = 0; cur < n; cur += batchSize) {
268 int num = std::min(batchSize, n - cur);
270 auto outDistancesSlice = outDistances.narrowOutermost(cur, num);
271 auto outIndicesSlice = outIndices.narrowOutermost(cur, num);
274 x + (
size_t) cur * (this->
d / 8),
276 outDistancesSlice.data(),
277 outIndicesSlice.data());
283 uint8_t* out)
const {
286 FAISS_THROW_IF_NOT_MSG(key < this->
ntotal,
"index out of bounds");
290 auto vec = vecs[key];
292 fromDevice(vec.data(), out, vecs.getSize(1), stream);
void reset()
Free all storage.
void reset() override
Removes all elements from the database.
Holder of GPU resources for a particular flat index.
void copyTo(faiss::IndexBinaryFlat *index) const
bool is_trained
set if the Index does not require training, or if training is done already
int device
GPU device on which the index is resident.
virtual cudaStream_t getDefaultStream(int device)=0
void add(faiss::IndexBinary::idx_t n, const uint8_t *x) override
GpuIndexBinaryFlatConfig config_
Configuration options.
void search(faiss::IndexBinary::idx_t n, const uint8_t *x, faiss::IndexBinary::idx_t k, int32_t *distances, faiss::IndexBinary::idx_t *labels) const override
GpuResources * resources_
Manages streans, cuBLAS handles and scratch memory for devices.
long idx_t
all indices are this type
void searchFromCpuPaged_(int n, const uint8_t *x, int k, int32_t *outDistancesData, int *outIndicesData) const
idx_t ntotal
total nb of indexed vectors
std::vector< uint8_t > xb
database vectors, size ntotal * d / 8
void reconstruct(faiss::IndexBinary::idx_t key, uint8_t *recons) const override
long idx_t
all indices are this type
void copyFrom(const faiss::IndexBinaryFlat *index)
GpuIndexBinaryFlat(GpuResources *resources, const faiss::IndexBinaryFlat *index, GpuIndexBinaryFlatConfig config=GpuIndexBinaryFlatConfig())
int getSize() const
Returns the number of vectors we contain.
void reserve(size_t numVecs, cudaStream_t stream)
Reserve storage that can contain at least this many vectors.
Tensor< unsigned char, 2, true > & getVectorsRef()
Returns a reference to our vectors currently in use.
void add(const unsigned char *data, int numVecs, cudaStream_t stream)