11 #include "../utils/DeviceUtils.h"
12 #include "../utils/BlockSelectKernel.cuh"
13 #include "../utils/WarpSelectKernel.cuh"
14 #include "../utils/HostTensor.cuh"
15 #include "../utils/DeviceTensor.cuh"
16 #include "../test/TestUtils.h"
18 #include <gtest/gtest.h>
20 #include <unordered_map>
23 int main(
int argc,
char** argv) {
24 testing::InitGoogleTest(&argc, argv);
25 return RUN_ALL_TESTS();
28 void testForSize(
int rows,
int cols,
int k,
bool dir,
bool warp) {
29 std::vector<float> v = faiss::gpu::randVecs(rows, cols);
32 for (
int r = 0; r < rows; ++r) {
33 for (
int c = 0; c < cols; ++c) {
34 hostVal[r][c] = v[r * cols + c];
39 std::unordered_map<int, std::vector<std::pair<int, float>>> hostOutValAndInd;
40 for (
int r = 0; r < rows; ++r) {
41 std::vector<std::pair<int, float>> closest;
43 for (
int c = 0; c < cols; ++c) {
44 closest.emplace_back(c, (
float) hostVal[r][c]);
48 [](std::pair<int, float>& a, std::pair<int, float>& b) {
49 return a.second < b.second;
52 [](std::pair<int, float>& a, std::pair<int, float>& b) {
53 return a.second > b.second;
56 std::sort(closest.begin(), closest.end(), dir ? dirTrueFn : dirFalseFn);
57 hostOutValAndInd.emplace(r, closest);
66 faiss::gpu::runWarpSelect(gpuVal, gpuOutVal, gpuOutInd, dir, k, 0);
68 faiss::gpu::runBlockSelect(gpuVal, gpuOutVal, gpuOutInd, dir, k, 0);
75 for (
int r = 0; r < rows; ++r) {
76 std::unordered_map<int, int> seenIndices;
78 for (
int i = 0; i < k; ++i) {
79 float gpuV = outVal[r][i];
80 float cpuV = hostOutValAndInd[r][i].second;
82 EXPECT_EQ(gpuV, cpuV) <<
83 "rows " << rows <<
" cols " << cols <<
" k " << k <<
" dir " << dir
84 <<
" row " << r <<
" ind " << i;
92 int gpuInd = outInd[r][i];
93 int cpuInd = hostOutValAndInd[r][i].first;
96 auto itSeenIndex = seenIndices.find(gpuInd);
98 EXPECT_EQ(itSeenIndex, seenIndices.end()) <<
99 "Row " << r <<
" user index " << gpuInd <<
" was seen at both " <<
100 itSeenIndex->second <<
" and " << i;
102 seenIndices[gpuInd] = i;
104 if (gpuInd != cpuInd) {
107 float gpuGatherV = hostVal[r][gpuInd];
108 float cpuGatherV = hostVal[r][cpuInd];
110 EXPECT_EQ(gpuGatherV, cpuGatherV) <<
111 "rows " << rows <<
" cols " << cols <<
" k " << k <<
" dir " << dir
112 <<
" row " << r <<
" ind " << i <<
" source ind "
113 << gpuInd <<
" " << cpuInd;
120 TEST(TestGpuSelect, test) {
121 for (
int i = 0; i < 10; ++i) {
122 int rows = faiss::gpu::randVal(10, 100);
123 int cols = faiss::gpu::randVal(1, 30000);
124 int k = std::min(cols, faiss::gpu::randVal(1, 1024));
125 bool dir = faiss::gpu::randBool();
127 testForSize(rows, cols, k, dir,
false);
132 TEST(TestGpuSelect, test1) {
133 for (
int i = 0; i < 5; ++i) {
134 int rows = faiss::gpu::randVal(10, 100);
135 int cols = faiss::gpu::randVal(1, 30000);
136 bool dir = faiss::gpu::randBool();
138 testForSize(rows, cols, 1, dir,
false);
144 TEST(TestGpuSelect, testExact) {
145 for (
int i = 0; i < 5; ++i) {
146 int rows = faiss::gpu::randVal(10, 100);
147 int cols = faiss::gpu::randVal(1, 1024);
148 bool dir = faiss::gpu::randBool();
150 testForSize(rows, cols, cols, dir,
false);
155 TEST(TestGpuSelect, testWarp) {
156 for (
int i = 0; i < 10; ++i) {
157 int rows = faiss::gpu::randVal(10, 100);
158 int cols = faiss::gpu::randVal(1, 30000);
159 int k = std::min(cols, faiss::gpu::randVal(1, 1024));
160 bool dir = faiss::gpu::randBool();
162 testForSize(rows, cols, k, dir,
true);
167 TEST(TestGpuSelect, test1Warp) {
168 for (
int i = 0; i < 5; ++i) {
169 int rows = faiss::gpu::randVal(10, 100);
170 int cols = faiss::gpu::randVal(1, 30000);
171 bool dir = faiss::gpu::randBool();
173 testForSize(rows, cols, 1, dir,
true);
179 TEST(TestGpuSelect, testExactWarp) {
180 for (
int i = 0; i < 5; ++i) {
181 int rows = faiss::gpu::randVal(10, 100);
182 int cols = faiss::gpu::randVal(1, 1024);
183 bool dir = faiss::gpu::randBool();
185 testForSize(rows, cols, cols, dir,
true);