11 #include "../../IndexFlat.h"
12 #include "../GpuIndexFlat.h"
13 #include "../StandardGpuResources.h"
14 #include "../utils/DeviceUtils.h"
15 #include "../test/TestUtils.h"
16 #include <gtest/gtest.h>
21 constexpr
float kF16MaxRelErr = 0.07f;
22 constexpr
float kF32MaxRelErr = 6e-3f;
30 numQueriesOverride(-1),
38 int numQueriesOverride;
43 int numVecs = opt.numVecsOverride > 0 ?
44 opt.numVecsOverride : faiss::gpu::randVal(1000, 20000);
45 int dim = faiss::gpu::randVal(50, 800);
46 int numQuery = opt.numQueriesOverride > 0 ?
47 opt.numQueriesOverride : faiss::gpu::randVal(1, 512);
52 int k = opt.useFloat16 ?
53 std::min(faiss::gpu::randVal(1, 50), numVecs) :
54 std::min(faiss::gpu::randVal(1, 1024), numVecs);
55 if (opt.kOverride > 0) {
68 int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
86 std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
87 cpuIndex->
add(numVecs, vecs.data());
88 gpuIndex->
add(numVecs, vecs.data());
90 std::stringstream str;
91 str << (opt.useL2 ?
"L2" :
"IP") <<
" numVecs " << numVecs
93 <<
" useFloat16 " << opt.useFloat16
94 <<
" transposed " << opt.useTransposed
95 <<
" numQuery " << numQuery
100 faiss::gpu::compareIndices(*cpuIndex, *gpuIndex, numQuery, dim, k, str.str(),
101 opt.useFloat16 ? kF16MaxRelErr : kF32MaxRelErr,
105 opt.useFloat16 ? 0.99f : 0.1f,
106 opt.useFloat16 ? 0.65f : 0.015f);
109 TEST(TestGpuIndexFlat, IP_Float32) {
110 for (
int tries = 0; tries < 5; ++tries) {
111 faiss::gpu::newTestSeed();
115 opt.useFloat16 =
false;
116 opt.useTransposed =
false;
120 opt.useTransposed =
true;
125 TEST(TestGpuIndexFlat, L2_Float32) {
126 for (
int tries = 0; tries < 5; ++tries) {
127 faiss::gpu::newTestSeed();
131 opt.useFloat16 =
false;
132 opt.useTransposed =
false;
136 opt.useTransposed =
true;
142 TEST(TestGpuIndexFlat, L2_Float32_K1) {
143 for (
int tries = 0; tries < 5; ++tries) {
144 faiss::gpu::newTestSeed();
148 opt.useFloat16 =
false;
149 opt.useTransposed =
false;
156 TEST(TestGpuIndexFlat, IP_Float16) {
157 for (
int tries = 0; tries < 5; ++tries) {
158 faiss::gpu::newTestSeed();
162 opt.useFloat16 =
true;
163 opt.useTransposed =
false;
167 opt.useTransposed =
true;
172 TEST(TestGpuIndexFlat, L2_Float16) {
173 for (
int tries = 0; tries < 5; ++tries) {
174 faiss::gpu::newTestSeed();
178 opt.useFloat16 =
true;
179 opt.useTransposed =
false;
183 opt.useTransposed =
true;
189 TEST(TestGpuIndexFlat, L2_Float16_K1) {
190 for (
int tries = 0; tries < 5; ++tries) {
191 faiss::gpu::newTestSeed();
195 opt.useFloat16 =
true;
196 opt.useTransposed =
false;
204 TEST(TestGpuIndexFlat, L2_Tiling) {
205 for (
int tries = 0; tries < 3; ++tries) {
206 faiss::gpu::newTestSeed();
210 opt.useFloat16 =
false;
211 opt.useTransposed =
false;
212 opt.numVecsOverride = 1000000;
213 opt.numQueriesOverride = 8;
217 opt.useTransposed =
true;
222 TEST(TestGpuIndexFlat, QueryEmpty) {
238 std::vector<float> queries(numQuery * dim, 1.0f);
240 std::vector<float> dist(numQuery * k, 0);
241 std::vector<faiss::Index::idx_t> ind(numQuery * k);
243 gpuIndex.
search(numQuery, queries.data(), k, dist.data(), ind.data());
245 for (
auto d : dist) {
246 EXPECT_EQ(d, std::numeric_limits<float>::max());
254 TEST(TestGpuIndexFlat, CopyFrom) {
255 faiss::gpu::newTestSeed();
257 int numVecs = faiss::gpu::randVal(100, 200);
258 int dim = faiss::gpu::randVal(1, 1000);
262 std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
263 cpuIndex.
add(numVecs, vecs.data());
269 int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
280 EXPECT_EQ(gpuIndex.
ntotal, numVecs);
282 EXPECT_EQ(cpuIndex.
d, gpuIndex.
d);
283 EXPECT_EQ(cpuIndex.
d, dim);
285 int idx = faiss::gpu::randVal(0, numVecs - 1);
287 std::vector<float> gpuVals(dim);
290 std::vector<float> cpuVals(dim);
293 EXPECT_EQ(gpuVals, cpuVals);
296 TEST(TestGpuIndexFlat, CopyTo) {
297 faiss::gpu::newTestSeed();
302 int numVecs = faiss::gpu::randVal(100, 200);
303 int dim = faiss::gpu::randVal(1, 1000);
305 int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
314 std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
315 gpuIndex.
add(numVecs, vecs.data());
319 gpuIndex.
copyTo(&cpuIndex);
322 EXPECT_EQ(gpuIndex.
ntotal, numVecs);
324 EXPECT_EQ(cpuIndex.
d, gpuIndex.
d);
325 EXPECT_EQ(cpuIndex.
d, dim);
327 int idx = faiss::gpu::randVal(0, numVecs - 1);
329 std::vector<float> gpuVals(dim);
332 std::vector<float> cpuVals(dim);
335 EXPECT_EQ(gpuVals, cpuVals);
338 TEST(TestGpuIndexFlat, UnifiedMemory) {
341 int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
343 if (!faiss::gpu::getFullUnifiedMemSupport(device)) {
352 size_t numVecs = 50000;
363 config.
memorySpace = faiss::gpu::MemorySpace::Unified;
367 std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
368 cpuIndexL2.add(numVecs, vecs.data());
369 gpuIndexL2.add(numVecs, vecs.data());
373 faiss::gpu::compareIndices(cpuIndexL2, gpuIndexL2,
374 numQuery, dim, k,
"Unified Memory",
void copyTo(faiss::IndexFlat *index) const
void reconstruct(idx_t key, float *recons) const override
bool useFloat16
Whether or not data is stored as float16.
int device
GPU device on which the index is resident.
void reconstruct(faiss::Index::idx_t key, float *out) const override
idx_t ntotal
total nb of indexed vectors
void add(idx_t n, const float *x) override
void copyFrom(const faiss::IndexFlat *index)
void add(faiss::Index::idx_t, const float *x) override
Overrides to avoid excessive copies.
void search(faiss::Index::idx_t n, const float *x, faiss::Index::idx_t k, float *distances, faiss::Index::idx_t *labels) const override