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;
24 void testFlat(
bool useL2,
28 int numVecs = faiss::gpu::randVal(1000, 20000);
29 int dim = faiss::gpu::randVal(50, 800);
30 int numQuery = faiss::gpu::randVal(1, 512);
36 std::min(faiss::gpu::randVal(1, 50), numVecs) :
37 std::min(faiss::gpu::randVal(1, 1024), numVecs);
50 int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
68 std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
69 cpuIndex->
add(numVecs, vecs.data());
70 gpuIndex->
add(numVecs, vecs.data());
72 std::stringstream str;
73 str << (useL2 ?
"L2" :
"IP") <<
" numVecs " << numVecs
75 <<
" useFloat16 " << useFloat16
76 <<
" transposed " << useTransposed
77 <<
" numQuery " << numQuery
82 faiss::gpu::compareIndices(*cpuIndex, *gpuIndex, numQuery, dim, k, str.str(),
83 useFloat16 ? kF16MaxRelErr : kF32MaxRelErr,
87 useFloat16 ? 0.99f : 0.1f,
88 useFloat16 ? 0.65f : 0.015f);
91 TEST(TestGpuIndexFlat, IP_Float32) {
92 for (
int tries = 0; tries < 5; ++tries) {
93 faiss::gpu::newTestSeed();
94 testFlat(
false,
false,
false);
95 testFlat(
false,
false,
true);
99 TEST(TestGpuIndexFlat, L2_Float32) {
100 for (
int tries = 0; tries < 5; ++tries) {
101 faiss::gpu::newTestSeed();
102 testFlat(
true,
false,
false);
103 testFlat(
true,
false,
true);
108 TEST(TestGpuIndexFlat, L2_Float32_K1) {
109 for (
int tries = 0; tries < 5; ++tries) {
110 faiss::gpu::newTestSeed();
111 testFlat(
true,
false,
false, 1);
112 testFlat(
true,
false,
true, 1);
116 TEST(TestGpuIndexFlat, IP_Float16) {
117 for (
int tries = 0; tries < 5; ++tries) {
118 faiss::gpu::newTestSeed();
119 testFlat(
false,
true,
false);
120 testFlat(
false,
true,
false);
124 TEST(TestGpuIndexFlat, L2_Float16) {
125 for (
int tries = 0; tries < 5; ++tries) {
126 faiss::gpu::newTestSeed();
127 testFlat(
true,
true,
false);
128 testFlat(
true,
true,
true);
133 TEST(TestGpuIndexFlat, L2_Float16_K1) {
134 for (
int tries = 0; tries < 5; ++tries) {
135 faiss::gpu::newTestSeed();
136 testFlat(
true,
true,
false, 1);
137 testFlat(
true,
true,
true, 1);
141 TEST(TestGpuIndexFlat, QueryEmpty) {
157 std::vector<float> queries(numQuery * dim, 1.0f);
159 std::vector<float> dist(numQuery * k, 0);
160 std::vector<faiss::Index::idx_t> ind(numQuery * k);
162 gpuIndex.
search(numQuery, queries.data(), k, dist.data(), ind.data());
164 for (
auto d : dist) {
165 EXPECT_EQ(d, std::numeric_limits<float>::max());
173 TEST(TestGpuIndexFlat, CopyFrom) {
174 faiss::gpu::newTestSeed();
176 int numVecs = faiss::gpu::randVal(100, 200);
177 int dim = faiss::gpu::randVal(1, 1000);
181 std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
182 cpuIndex.
add(numVecs, vecs.data());
188 int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
199 EXPECT_EQ(gpuIndex.
ntotal, numVecs);
201 EXPECT_EQ(cpuIndex.
d, gpuIndex.
d);
202 EXPECT_EQ(cpuIndex.
d, dim);
204 int idx = faiss::gpu::randVal(0, numVecs - 1);
206 std::vector<float> gpuVals(dim);
209 std::vector<float> cpuVals(dim);
212 EXPECT_EQ(gpuVals, cpuVals);
215 TEST(TestGpuIndexFlat, CopyTo) {
216 faiss::gpu::newTestSeed();
221 int numVecs = faiss::gpu::randVal(100, 200);
222 int dim = faiss::gpu::randVal(1, 1000);
224 int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
233 std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
234 gpuIndex.
add(numVecs, vecs.data());
238 gpuIndex.
copyTo(&cpuIndex);
241 EXPECT_EQ(gpuIndex.
ntotal, numVecs);
243 EXPECT_EQ(cpuIndex.
d, gpuIndex.
d);
244 EXPECT_EQ(cpuIndex.
d, dim);
246 int idx = faiss::gpu::randVal(0, numVecs - 1);
248 std::vector<float> gpuVals(dim);
251 std::vector<float> cpuVals(dim);
254 EXPECT_EQ(gpuVals, cpuVals);
257 TEST(TestGpuIndexFlat, UnifiedMemory) {
260 int device = faiss::gpu::randVal(0, faiss::gpu::getNumDevices() - 1);
262 if (!faiss::gpu::getFullUnifiedMemSupport(device)) {
271 size_t numVecs = 50000;
282 config.
memorySpace = faiss::gpu::MemorySpace::Unified;
286 std::vector<float> vecs = faiss::gpu::randVecs(numVecs, dim);
287 cpuIndexL2.add(numVecs, vecs.data());
288 gpuIndexL2.add(numVecs, vecs.data());
292 faiss::gpu::compareIndices(cpuIndexL2, gpuIndexL2,
293 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