8 #include "GpuIndexBinaryFlat.h"
10 #include "GpuResources.h"
11 #include "impl/BinaryFlatIndex.cuh"
12 #include "utils/ConversionOperators.cuh"
13 #include "utils/CopyUtils.cuh"
14 #include "utils/DeviceUtils.h"
16 #include <thrust/execution_policy.h>
17 #include <thrust/transform.h>
19 namespace faiss {
namespace gpu {
22 constexpr
size_t kMinPageSize = (size_t) 256 * 1024 * 1024;
28 resources_(resources),
29 config_(std::move(config)),
31 FAISS_THROW_IF_NOT_FMT(this->
d % 8 == 0,
32 "vector dimension (number of bits) "
33 "must be divisible by 8 (passed %d)",
47 resources_(resources),
48 config_(std::move(config)),
50 FAISS_THROW_IF_NOT_FMT(this->
d % 8 == 0,
51 "vector dimension (number of bits) "
52 "must be divisible by 8 (passed %d)",
65 GpuIndexBinaryFlat::~GpuIndexBinaryFlat() {
76 FAISS_THROW_IF_NOT_FMT(index->
ntotal <=
78 "GPU index only supports up to %zu indices; "
79 "attempting to copy CPU index with %zu parameters",
80 (
size_t) std::numeric_limits<int>::max(),
106 index->
xb.resize(this->
ntotal * (this->
d / 8));
126 FAISS_THROW_IF_NOT_FMT(this->
ntotal + n <=
128 "GPU index only supports up to %zu indices",
129 (
size_t) std::numeric_limits<int>::max());
131 data_->
add((
const unsigned char*) x,
157 FAISS_THROW_IF_NOT_FMT(n <= (
Index::idx_t) std::numeric_limits<int>::max(),
158 "GPU index only supports up to %zu indices",
159 (
size_t) std::numeric_limits<int>::max());
160 FAISS_THROW_IF_NOT_FMT(k <= (
Index::idx_t) getMaxKSelection(),
161 "GPU only supports k <= %d (requested %d)",
174 auto outDistances = toDevice<int32_t, 2>(
resources_,
182 resources_->getMemoryManagerCurrentDevice(),
183 {(int) n, (
int) k}, stream);
185 bool usePaged =
false;
187 if (getDeviceForAddress(x) == -1) {
194 size_t dataSize = (size_t) n * (this->
d / 8) *
sizeof(uint8_t);
196 if (dataSize >= kMinPageSize) {
199 outIntIndices.data());
205 searchNonPaged_(n, x, k,
207 outIntIndices.data());
211 auto outIndices = toDevice<faiss::Index::idx_t, 2>(
resources_,
218 thrust::transform(thrust::cuda::par.on(stream),
219 outIntIndices.data(),
225 fromDevice<int32_t, 2>(outDistances, distances, stream);
226 fromDevice<faiss::Index::idx_t, 2>(outIndices, labels, stream);
230 GpuIndexBinaryFlat::searchNonPaged_(
int n,
233 int32_t* outDistancesData,
234 int* outIndicesData)
const {
236 Tensor<int, 2, true> outIndices(outIndicesData, {n, k});
244 const_cast<uint8_t*
>(x),
246 {n, (int) (this->
d / 8)});
248 data_->query(vecs, k, outDistances, outIndices);
255 int32_t* outDistancesData,
256 int* outIndicesData)
const {
260 auto vectorSize =
sizeof(uint8_t) * (this->
d / 8);
263 int batchSize = utils::nextHighestPowerOf2(
264 (
int) ((
size_t) kMinPageSize / vectorSize));
266 for (
int cur = 0; cur < n; cur += batchSize) {
267 int num = std::min(batchSize, n - cur);
269 auto outDistancesSlice = outDistances.narrowOutermost(cur, num);
270 auto outIndicesSlice = outIndices.narrowOutermost(cur, num);
273 x + (
size_t) cur * (this->
d / 8),
275 outDistancesSlice.data(),
276 outIndicesSlice.data());
282 uint8_t* out)
const {
285 FAISS_THROW_IF_NOT_MSG(key < this->
ntotal,
"index out of bounds");
289 auto vec = vecs[key];
291 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
Index::idx_t idx_t
all indices are this type
long idx_t
all indices are this type
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.
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
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)