10 #include "../utils/DeviceUtils.h"
11 #include "../utils/BlockSelectKernel.cuh"
12 #include "../utils/WarpSelectKernel.cuh"
13 #include "../utils/HostTensor.cuh"
14 #include "../utils/DeviceTensor.cuh"
15 #include "../test/TestUtils.h"
17 #include <gtest/gtest.h>
19 #include <unordered_map>
22 void testForSize(
int rows,
int cols,
int k,
bool dir,
bool warp) {
23 std::vector<float> v = faiss::gpu::randVecs(rows, cols);
26 for (
int r = 0; r < rows; ++r) {
27 for (
int c = 0; c < cols; ++c) {
28 hostVal[r][c] = v[r * cols + c];
33 std::unordered_map<int, std::vector<std::pair<int, float>>> hostOutValAndInd;
34 for (
int r = 0; r < rows; ++r) {
35 std::vector<std::pair<int, float>> closest;
37 for (
int c = 0; c < cols; ++c) {
38 closest.emplace_back(c, (
float) hostVal[r][c]);
42 [](std::pair<int, float>& a, std::pair<int, float>& b) {
43 return a.second < b.second;
46 [](std::pair<int, float>& a, std::pair<int, float>& b) {
47 return a.second > b.second;
50 std::sort(closest.begin(), closest.end(), dir ? dirTrueFn : dirFalseFn);
51 hostOutValAndInd.emplace(r, closest);
60 faiss::gpu::runWarpSelect(gpuVal, gpuOutVal, gpuOutInd, dir, k, 0);
62 faiss::gpu::runBlockSelect(gpuVal, gpuOutVal, gpuOutInd, dir, k, 0);
69 for (
int r = 0; r < rows; ++r) {
70 std::unordered_map<int, int> seenIndices;
72 for (
int i = 0; i < k; ++i) {
73 float gpuV = outVal[r][i];
74 float cpuV = hostOutValAndInd[r][i].second;
76 EXPECT_EQ(gpuV, cpuV) <<
77 "rows " << rows <<
" cols " << cols <<
" k " << k <<
" dir " << dir
78 <<
" row " << r <<
" ind " << i;
86 int gpuInd = outInd[r][i];
87 int cpuInd = hostOutValAndInd[r][i].first;
90 auto itSeenIndex = seenIndices.find(gpuInd);
92 EXPECT_EQ(itSeenIndex, seenIndices.end()) <<
93 "Row " << r <<
" user index " << gpuInd <<
" was seen at both " <<
94 itSeenIndex->second <<
" and " << i;
96 seenIndices[gpuInd] = i;
98 if (gpuInd != cpuInd) {
101 float gpuGatherV = hostVal[r][gpuInd];
102 float cpuGatherV = hostVal[r][cpuInd];
104 EXPECT_EQ(gpuGatherV, cpuGatherV) <<
105 "rows " << rows <<
" cols " << cols <<
" k " << k <<
" dir " << dir
106 <<
" row " << r <<
" ind " << i <<
" source ind "
107 << gpuInd <<
" " << cpuInd;
114 TEST(TestGpuSelect, test) {
115 for (
int i = 0; i < 10; ++i) {
116 int rows = faiss::gpu::randVal(10, 100);
117 int cols = faiss::gpu::randVal(1, 30000);
118 int k = std::min(cols, faiss::gpu::randVal(1, 1024));
119 bool dir = faiss::gpu::randBool();
121 testForSize(rows, cols, k, dir,
false);
126 TEST(TestGpuSelect, test1) {
127 for (
int i = 0; i < 5; ++i) {
128 int rows = faiss::gpu::randVal(10, 100);
129 int cols = faiss::gpu::randVal(1, 30000);
130 bool dir = faiss::gpu::randBool();
132 testForSize(rows, cols, 1, dir,
false);
138 TEST(TestGpuSelect, testExact) {
139 for (
int i = 0; i < 5; ++i) {
140 int rows = faiss::gpu::randVal(10, 100);
141 int cols = faiss::gpu::randVal(1, 1024);
142 bool dir = faiss::gpu::randBool();
144 testForSize(rows, cols, cols, dir,
false);
149 TEST(TestGpuSelect, testWarp) {
150 for (
int i = 0; i < 10; ++i) {
151 int rows = faiss::gpu::randVal(10, 100);
152 int cols = faiss::gpu::randVal(1, 30000);
153 int k = std::min(cols, faiss::gpu::randVal(1, 1024));
154 bool dir = faiss::gpu::randBool();
156 testForSize(rows, cols, k, dir,
true);
161 TEST(TestGpuSelect, test1Warp) {
162 for (
int i = 0; i < 5; ++i) {
163 int rows = faiss::gpu::randVal(10, 100);
164 int cols = faiss::gpu::randVal(1, 30000);
165 bool dir = faiss::gpu::randBool();
167 testForSize(rows, cols, 1, dir,
true);
173 TEST(TestGpuSelect, testExactWarp) {
174 for (
int i = 0; i < 5; ++i) {
175 int rows = faiss::gpu::randVal(10, 100);
176 int cols = faiss::gpu::randVal(1, 1024);
177 bool dir = faiss::gpu::randBool();
179 testForSize(rows, cols, cols, dir,
true);
183 int main(
int argc,
char** argv) {
184 testing::InitGoogleTest(&argc, argv);
187 faiss::gpu::setTestSeed(100);
189 return RUN_ALL_TESTS();