12 #include "../utils/DeviceUtils.h"
13 #include "../utils/BlockSelectKernel.cuh"
14 #include "../utils/WarpSelectKernel.cuh"
15 #include "../utils/HostTensor.cuh"
16 #include "../utils/DeviceTensor.cuh"
17 #include "../test/TestUtils.h"
19 #include <gtest/gtest.h>
21 #include <unordered_map>
24 int main(
int argc,
char** argv) {
25 testing::InitGoogleTest(&argc, argv);
26 return RUN_ALL_TESTS();
29 void testForSize(
int rows,
int cols,
int k,
bool dir,
bool warp) {
30 std::vector<float> v = faiss::gpu::randVecs(rows, cols);
33 for (
int r = 0; r < rows; ++r) {
34 for (
int c = 0; c < cols; ++c) {
35 hostVal[r][c] = v[r * cols + c];
40 std::unordered_map<int, std::vector<std::pair<int, float>>> hostOutValAndInd;
41 for (
int r = 0; r < rows; ++r) {
42 std::vector<std::pair<int, float>> closest;
44 for (
int c = 0; c < cols; ++c) {
45 closest.emplace_back(c, (
float) hostVal[r][c]);
49 [](std::pair<int, float>& a, std::pair<int, float>& b) {
50 return a.second < b.second;
53 [](std::pair<int, float>& a, std::pair<int, float>& b) {
54 return a.second > b.second;
57 std::sort(closest.begin(), closest.end(), dir ? dirTrueFn : dirFalseFn);
58 hostOutValAndInd.emplace(r, closest);
67 faiss::gpu::runWarpSelect(gpuVal, gpuOutVal, gpuOutInd, dir, k, 0);
69 faiss::gpu::runBlockSelect(gpuVal, gpuOutVal, gpuOutInd, dir, k, 0);
76 for (
int r = 0; r < rows; ++r) {
77 std::unordered_map<int, int> seenIndices;
79 for (
int i = 0; i < k; ++i) {
80 float gpuV = outVal[r][i];
81 float cpuV = hostOutValAndInd[r][i].second;
83 EXPECT_EQ(gpuV, cpuV) <<
84 "rows " << rows <<
" cols " << cols <<
" k " << k <<
" dir " << dir
85 <<
" row " << r <<
" ind " << i;
93 int gpuInd = outInd[r][i];
94 int cpuInd = hostOutValAndInd[r][i].first;
97 auto itSeenIndex = seenIndices.find(gpuInd);
99 EXPECT_EQ(itSeenIndex, seenIndices.end()) <<
100 "Row " << r <<
" user index " << gpuInd <<
" was seen at both " <<
101 itSeenIndex->second <<
" and " << i;
103 seenIndices[gpuInd] = i;
105 if (gpuInd != cpuInd) {
108 float gpuGatherV = hostVal[r][gpuInd];
109 float cpuGatherV = hostVal[r][cpuInd];
111 EXPECT_EQ(gpuGatherV, cpuGatherV) <<
112 "rows " << rows <<
" cols " << cols <<
" k " << k <<
" dir " << dir
113 <<
" row " << r <<
" ind " << i <<
" source ind "
114 << gpuInd <<
" " << cpuInd;
121 TEST(TestGpuSelect, test) {
122 for (
int i = 0; i < 10; ++i) {
123 int rows = faiss::gpu::randVal(10, 100);
124 int cols = faiss::gpu::randVal(1, 30000);
125 int k = std::min(cols, faiss::gpu::randVal(1, 1024));
126 bool dir = faiss::gpu::randBool();
128 testForSize(rows, cols, k, dir,
false);
133 TEST(TestGpuSelect, test1) {
134 for (
int i = 0; i < 5; ++i) {
135 int rows = faiss::gpu::randVal(10, 100);
136 int cols = faiss::gpu::randVal(1, 30000);
137 bool dir = faiss::gpu::randBool();
139 testForSize(rows, cols, 1, dir,
false);
145 TEST(TestGpuSelect, testExact) {
146 for (
int i = 0; i < 5; ++i) {
147 int rows = faiss::gpu::randVal(10, 100);
148 int cols = faiss::gpu::randVal(1, 1024);
149 bool dir = faiss::gpu::randBool();
151 testForSize(rows, cols, cols, dir,
false);
156 TEST(TestGpuSelect, testWarp) {
157 for (
int i = 0; i < 10; ++i) {
158 int rows = faiss::gpu::randVal(10, 100);
159 int cols = faiss::gpu::randVal(1, 30000);
160 int k = std::min(cols, faiss::gpu::randVal(1, 1024));
161 bool dir = faiss::gpu::randBool();
163 testForSize(rows, cols, k, dir,
true);
168 TEST(TestGpuSelect, test1Warp) {
169 for (
int i = 0; i < 5; ++i) {
170 int rows = faiss::gpu::randVal(10, 100);
171 int cols = faiss::gpu::randVal(1, 30000);
172 bool dir = faiss::gpu::randBool();
174 testForSize(rows, cols, 1, dir,
true);
180 TEST(TestGpuSelect, testExactWarp) {
181 for (
int i = 0; i < 5; ++i) {
182 int rows = faiss::gpu::randVal(10, 100);
183 int cols = faiss::gpu::randVal(1, 1024);
184 bool dir = faiss::gpu::randBool();
186 testForSize(rows, cols, cols, dir,
true);