faiss 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +23 -21
  4. data/ext/faiss/extconf.rb +11 -0
  5. data/ext/faiss/index.cpp +4 -4
  6. data/ext/faiss/index_binary.cpp +6 -6
  7. data/ext/faiss/product_quantizer.cpp +4 -4
  8. data/lib/faiss/version.rb +1 -1
  9. data/vendor/faiss/faiss/AutoTune.cpp +13 -0
  10. data/vendor/faiss/faiss/IVFlib.cpp +101 -2
  11. data/vendor/faiss/faiss/IVFlib.h +26 -2
  12. data/vendor/faiss/faiss/Index.cpp +36 -3
  13. data/vendor/faiss/faiss/Index.h +43 -6
  14. data/vendor/faiss/faiss/Index2Layer.cpp +6 -2
  15. data/vendor/faiss/faiss/Index2Layer.h +6 -1
  16. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +219 -16
  17. data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +63 -5
  18. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +299 -0
  19. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +199 -0
  20. data/vendor/faiss/faiss/IndexBinary.cpp +20 -4
  21. data/vendor/faiss/faiss/IndexBinary.h +18 -3
  22. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +9 -2
  23. data/vendor/faiss/faiss/IndexBinaryFlat.h +4 -2
  24. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +4 -1
  25. data/vendor/faiss/faiss/IndexBinaryFromFloat.h +2 -1
  26. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +5 -1
  27. data/vendor/faiss/faiss/IndexBinaryHNSW.h +2 -1
  28. data/vendor/faiss/faiss/IndexBinaryHash.cpp +17 -4
  29. data/vendor/faiss/faiss/IndexBinaryHash.h +8 -4
  30. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +28 -13
  31. data/vendor/faiss/faiss/IndexBinaryIVF.h +10 -7
  32. data/vendor/faiss/faiss/IndexFastScan.cpp +626 -0
  33. data/vendor/faiss/faiss/IndexFastScan.h +145 -0
  34. data/vendor/faiss/faiss/IndexFlat.cpp +34 -21
  35. data/vendor/faiss/faiss/IndexFlat.h +7 -4
  36. data/vendor/faiss/faiss/IndexFlatCodes.cpp +35 -1
  37. data/vendor/faiss/faiss/IndexFlatCodes.h +12 -0
  38. data/vendor/faiss/faiss/IndexHNSW.cpp +66 -138
  39. data/vendor/faiss/faiss/IndexHNSW.h +4 -2
  40. data/vendor/faiss/faiss/IndexIDMap.cpp +247 -0
  41. data/vendor/faiss/faiss/IndexIDMap.h +107 -0
  42. data/vendor/faiss/faiss/IndexIVF.cpp +121 -33
  43. data/vendor/faiss/faiss/IndexIVF.h +35 -16
  44. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +84 -7
  45. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +63 -1
  46. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +590 -0
  47. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +171 -0
  48. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +1290 -0
  49. data/vendor/faiss/faiss/IndexIVFFastScan.h +213 -0
  50. data/vendor/faiss/faiss/IndexIVFFlat.cpp +37 -17
  51. data/vendor/faiss/faiss/IndexIVFFlat.h +4 -2
  52. data/vendor/faiss/faiss/IndexIVFPQ.cpp +234 -50
  53. data/vendor/faiss/faiss/IndexIVFPQ.h +5 -1
  54. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +23 -852
  55. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +7 -112
  56. data/vendor/faiss/faiss/IndexIVFPQR.cpp +3 -3
  57. data/vendor/faiss/faiss/IndexIVFPQR.h +1 -1
  58. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +3 -1
  59. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +2 -1
  60. data/vendor/faiss/faiss/IndexLSH.cpp +4 -2
  61. data/vendor/faiss/faiss/IndexLSH.h +2 -1
  62. data/vendor/faiss/faiss/IndexLattice.cpp +7 -1
  63. data/vendor/faiss/faiss/IndexLattice.h +3 -1
  64. data/vendor/faiss/faiss/IndexNNDescent.cpp +4 -3
  65. data/vendor/faiss/faiss/IndexNNDescent.h +2 -1
  66. data/vendor/faiss/faiss/IndexNSG.cpp +37 -3
  67. data/vendor/faiss/faiss/IndexNSG.h +25 -1
  68. data/vendor/faiss/faiss/IndexPQ.cpp +106 -69
  69. data/vendor/faiss/faiss/IndexPQ.h +19 -5
  70. data/vendor/faiss/faiss/IndexPQFastScan.cpp +15 -450
  71. data/vendor/faiss/faiss/IndexPQFastScan.h +15 -78
  72. data/vendor/faiss/faiss/IndexPreTransform.cpp +47 -8
  73. data/vendor/faiss/faiss/IndexPreTransform.h +15 -3
  74. data/vendor/faiss/faiss/IndexRefine.cpp +8 -4
  75. data/vendor/faiss/faiss/IndexRefine.h +4 -2
  76. data/vendor/faiss/faiss/IndexReplicas.cpp +4 -2
  77. data/vendor/faiss/faiss/IndexReplicas.h +2 -1
  78. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +438 -0
  79. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +92 -0
  80. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +26 -15
  81. data/vendor/faiss/faiss/IndexScalarQuantizer.h +6 -7
  82. data/vendor/faiss/faiss/IndexShards.cpp +4 -1
  83. data/vendor/faiss/faiss/IndexShards.h +2 -1
  84. data/vendor/faiss/faiss/MetaIndexes.cpp +5 -178
  85. data/vendor/faiss/faiss/MetaIndexes.h +3 -81
  86. data/vendor/faiss/faiss/VectorTransform.cpp +43 -0
  87. data/vendor/faiss/faiss/VectorTransform.h +22 -4
  88. data/vendor/faiss/faiss/clone_index.cpp +23 -1
  89. data/vendor/faiss/faiss/clone_index.h +3 -0
  90. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +300 -0
  91. data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +24 -0
  92. data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +195 -0
  93. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +2058 -0
  94. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +408 -0
  95. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +2147 -0
  96. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +460 -0
  97. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +465 -0
  98. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +1618 -0
  99. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +251 -0
  100. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +1452 -0
  101. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +1 -0
  102. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +0 -4
  103. data/vendor/faiss/faiss/gpu/GpuIndex.h +28 -4
  104. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +2 -1
  105. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +10 -8
  106. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +75 -14
  107. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +19 -32
  108. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -31
  109. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +22 -28
  110. data/vendor/faiss/faiss/gpu/GpuResources.cpp +14 -0
  111. data/vendor/faiss/faiss/gpu/GpuResources.h +16 -3
  112. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +3 -3
  113. data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +32 -0
  114. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +1 -0
  115. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +311 -75
  116. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +10 -0
  117. data/vendor/faiss/faiss/gpu/test/TestUtils.h +3 -0
  118. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +2 -2
  119. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +5 -4
  120. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +116 -47
  121. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +44 -13
  122. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +0 -54
  123. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +0 -76
  124. data/vendor/faiss/faiss/impl/DistanceComputer.h +64 -0
  125. data/vendor/faiss/faiss/impl/HNSW.cpp +123 -27
  126. data/vendor/faiss/faiss/impl/HNSW.h +19 -16
  127. data/vendor/faiss/faiss/impl/IDSelector.cpp +125 -0
  128. data/vendor/faiss/faiss/impl/IDSelector.h +135 -0
  129. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +6 -28
  130. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +6 -1
  131. data/vendor/faiss/faiss/impl/LookupTableScaler.h +77 -0
  132. data/vendor/faiss/faiss/impl/NNDescent.cpp +1 -0
  133. data/vendor/faiss/faiss/impl/NSG.cpp +1 -1
  134. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +383 -0
  135. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +154 -0
  136. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +225 -145
  137. data/vendor/faiss/faiss/impl/ProductQuantizer.h +29 -10
  138. data/vendor/faiss/faiss/impl/Quantizer.h +43 -0
  139. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +192 -36
  140. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +40 -20
  141. data/vendor/faiss/faiss/impl/ResultHandler.h +96 -0
  142. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +97 -173
  143. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +18 -18
  144. data/vendor/faiss/faiss/impl/index_read.cpp +240 -9
  145. data/vendor/faiss/faiss/impl/index_write.cpp +237 -5
  146. data/vendor/faiss/faiss/impl/kmeans1d.cpp +6 -4
  147. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +56 -16
  148. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +25 -8
  149. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +66 -25
  150. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +75 -27
  151. data/vendor/faiss/faiss/index_factory.cpp +196 -7
  152. data/vendor/faiss/faiss/index_io.h +5 -0
  153. data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -0
  154. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +4 -1
  155. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +2 -1
  156. data/vendor/faiss/faiss/python/python_callbacks.cpp +27 -0
  157. data/vendor/faiss/faiss/python/python_callbacks.h +15 -0
  158. data/vendor/faiss/faiss/utils/Heap.h +31 -15
  159. data/vendor/faiss/faiss/utils/distances.cpp +380 -56
  160. data/vendor/faiss/faiss/utils/distances.h +113 -15
  161. data/vendor/faiss/faiss/utils/distances_simd.cpp +726 -6
  162. data/vendor/faiss/faiss/utils/extra_distances.cpp +12 -7
  163. data/vendor/faiss/faiss/utils/extra_distances.h +3 -1
  164. data/vendor/faiss/faiss/utils/fp16-fp16c.h +21 -0
  165. data/vendor/faiss/faiss/utils/fp16-inl.h +101 -0
  166. data/vendor/faiss/faiss/utils/fp16.h +11 -0
  167. data/vendor/faiss/faiss/utils/hamming-inl.h +54 -0
  168. data/vendor/faiss/faiss/utils/hamming.cpp +0 -48
  169. data/vendor/faiss/faiss/utils/ordered_key_value.h +10 -0
  170. data/vendor/faiss/faiss/utils/quantize_lut.cpp +62 -0
  171. data/vendor/faiss/faiss/utils/quantize_lut.h +20 -0
  172. data/vendor/faiss/faiss/utils/random.cpp +53 -0
  173. data/vendor/faiss/faiss/utils/random.h +5 -0
  174. data/vendor/faiss/faiss/utils/simdlib_avx2.h +4 -0
  175. data/vendor/faiss/faiss/utils/simdlib_emulated.h +6 -1
  176. data/vendor/faiss/faiss/utils/simdlib_neon.h +7 -2
  177. metadata +37 -3
@@ -0,0 +1,408 @@
1
+ // (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary.
2
+ #ifndef LEVEL2_INL_H
3
+ #define LEVEL2_INL_H
4
+
5
+ #include <cstddef>
6
+ #include <cstdint>
7
+
8
+ #include <faiss/cppcontrib/detail/CoarseBitType.h>
9
+
10
+ namespace faiss {
11
+ namespace cppcontrib {
12
+
13
+ ////////////////////////////////////////////////////////////////////////////////////
14
+ /// Index2LevelDecoder
15
+ ////////////////////////////////////////////////////////////////////////////////////
16
+
17
+ // Suitable for IVF256,PQ[1]x8
18
+ // Suitable for Residual[1]x8,PQ[2]x8
19
+ // Suitable for IVF[9-16 bit],PQ[1]x8 (such as IVF1024,PQ16np)
20
+ // Suitable for Residual1x[9-16 bit],PQ[1]x8 (such as Residual1x9,PQ8)
21
+ template <
22
+ intptr_t DIM,
23
+ intptr_t COARSE_SIZE,
24
+ intptr_t FINE_SIZE,
25
+ intptr_t COARSE_BITS = 8,
26
+ intptr_t FINE_BITS = 8>
27
+ struct Index2LevelDecoder {
28
+ static_assert(
29
+ COARSE_BITS == 8 || COARSE_BITS == 16,
30
+ "Only 8 or 16 bits are currently supported for COARSE_BITS");
31
+ static_assert(
32
+ FINE_BITS == 8,
33
+ "Only 8 bits is currently supported for FINE_BITS");
34
+
35
+ static constexpr intptr_t dim = DIM;
36
+ static constexpr intptr_t coarseSize = COARSE_SIZE;
37
+ static constexpr intptr_t fineSize = FINE_SIZE;
38
+ static constexpr intptr_t coarseBits = COARSE_BITS;
39
+ static constexpr intptr_t fineBits = FINE_BITS;
40
+
41
+ // coarse quantizer storage
42
+ using coarse_storage_type =
43
+ typename detail::CoarseBitType<COARSE_BITS>::bit_type;
44
+ static constexpr intptr_t COARSE_TABLE_BYTES = (1 << COARSE_BITS);
45
+
46
+ static constexpr intptr_t FINE_TABLE_BYTES = (1 << FINE_BITS);
47
+
48
+ // Process 1 sample.
49
+ // Performs outputStore = decoded(code)
50
+ static void store(
51
+ const float* const __restrict pqCoarseCentroids,
52
+ const float* const __restrict pqFineCentroids,
53
+ const uint8_t* const __restrict code,
54
+ float* const __restrict outputStore) {
55
+ // coarse quantizer
56
+ const coarse_storage_type* const __restrict coarse =
57
+ reinterpret_cast<const coarse_storage_type*>(code);
58
+
59
+ // fine quantizer
60
+ const uint8_t* const __restrict fine =
61
+ code + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
62
+
63
+ #pragma unroll
64
+ for (intptr_t i = 0; i < DIM; i++) {
65
+ const intptr_t coarseCentroidIdx = i / COARSE_SIZE;
66
+ const intptr_t coarseCentroidOffset = i % COARSE_SIZE;
67
+ const intptr_t fineCentroidIdx = i / FINE_SIZE;
68
+ const intptr_t fineCentroidOffset = i % FINE_SIZE;
69
+
70
+ const intptr_t coarseCode = coarse[coarseCentroidIdx];
71
+ const intptr_t fineCode = fine[fineCentroidIdx];
72
+
73
+ const float* const __restrict coarsePtr = pqCoarseCentroids +
74
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode) *
75
+ COARSE_SIZE +
76
+ coarseCentroidOffset;
77
+ const float* const __restrict finePtr = pqFineCentroids +
78
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode) *
79
+ FINE_SIZE +
80
+ fineCentroidOffset;
81
+
82
+ outputStore[i] = *coarsePtr + *finePtr;
83
+ }
84
+ }
85
+
86
+ // Process 1 sample.
87
+ // Performs outputAccum += weight * decoded(code)
88
+ static void accum(
89
+ const float* const __restrict pqCoarseCentroids,
90
+ const float* const __restrict pqFineCentroids,
91
+ const uint8_t* const __restrict code,
92
+ const float weight,
93
+ float* const __restrict outputAccum) {
94
+ // coarse quantizer
95
+ const coarse_storage_type* const __restrict coarse =
96
+ reinterpret_cast<const coarse_storage_type*>(code);
97
+
98
+ // fine quantizer
99
+ const uint8_t* const __restrict fine =
100
+ code + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
101
+
102
+ #pragma unroll
103
+ for (intptr_t i = 0; i < DIM; i++) {
104
+ const intptr_t coarseCentroidIdx = i / COARSE_SIZE;
105
+ const intptr_t coarseCentroidOffset = i % COARSE_SIZE;
106
+ const intptr_t fineCentroidIdx = i / FINE_SIZE;
107
+ const intptr_t fineCentroidOffset = i % FINE_SIZE;
108
+
109
+ const intptr_t coarseCode = coarse[coarseCentroidIdx];
110
+ const intptr_t fineCode = fine[fineCentroidIdx];
111
+
112
+ const float* const __restrict coarsePtr = pqCoarseCentroids +
113
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode) *
114
+ COARSE_SIZE +
115
+ coarseCentroidOffset;
116
+ const float* const __restrict finePtr = pqFineCentroids +
117
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode) *
118
+ FINE_SIZE +
119
+ fineCentroidOffset;
120
+
121
+ outputAccum[i] += weight * (*coarsePtr + *finePtr);
122
+ }
123
+ }
124
+
125
+ // Process 2 samples.
126
+ // Each code uses its own coarse pq centroids table and fine pq centroids
127
+ // table.
128
+ //
129
+ // Performs outputAccum += weight0 * decoded(code0) + weight1 *
130
+ // decoded(code1).
131
+ static void accum(
132
+ const float* const __restrict pqCoarseCentroids0,
133
+ const float* const __restrict pqFineCentroids0,
134
+ const uint8_t* const __restrict code0,
135
+ const float weight0,
136
+ const float* const __restrict pqCoarseCentroids1,
137
+ const float* const __restrict pqFineCentroids1,
138
+ const uint8_t* const __restrict code1,
139
+ const float weight1,
140
+ float* const __restrict outputAccum) {
141
+ // coarse quantizer
142
+ const coarse_storage_type* const __restrict coarse0 =
143
+ reinterpret_cast<const coarse_storage_type*>(code0);
144
+ const coarse_storage_type* const __restrict coarse1 =
145
+ reinterpret_cast<const coarse_storage_type*>(code1);
146
+
147
+ // fine quantizer
148
+ const uint8_t* const __restrict fine0 =
149
+ code0 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
150
+ const uint8_t* const __restrict fine1 =
151
+ code1 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
152
+
153
+ #pragma unroll
154
+ for (intptr_t i = 0; i < DIM; i++) {
155
+ const intptr_t coarseCentroidIdx = i / COARSE_SIZE;
156
+ const intptr_t coarseCentroidOffset = i % COARSE_SIZE;
157
+ const intptr_t fineCentroidIdx = i / FINE_SIZE;
158
+ const intptr_t fineCentroidOffset = i % FINE_SIZE;
159
+
160
+ const intptr_t coarseCode0 = coarse0[coarseCentroidIdx];
161
+ const intptr_t fineCode0 = fine0[fineCentroidIdx];
162
+ const intptr_t coarseCode1 = coarse1[coarseCentroidIdx];
163
+ const intptr_t fineCode1 = fine1[fineCentroidIdx];
164
+
165
+ const float* const __restrict coarsePtr0 = pqCoarseCentroids0 +
166
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode0) *
167
+ COARSE_SIZE +
168
+ coarseCentroidOffset;
169
+ const float* const __restrict finePtr0 = pqFineCentroids0 +
170
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode0) *
171
+ FINE_SIZE +
172
+ fineCentroidOffset;
173
+ const float* const __restrict coarsePtr1 = pqCoarseCentroids1 +
174
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode1) *
175
+ COARSE_SIZE +
176
+ coarseCentroidOffset;
177
+ const float* const __restrict finePtr1 = pqFineCentroids1 +
178
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode1) *
179
+ FINE_SIZE +
180
+ fineCentroidOffset;
181
+
182
+ outputAccum[i] += weight0 * (*coarsePtr0 + *finePtr0) +
183
+ weight1 * (*coarsePtr1 + *finePtr1);
184
+ }
185
+ }
186
+
187
+ // Process 2 samples.
188
+ // Coarse pq centroids table and fine pq centroids table are shared among
189
+ // codes.
190
+ //
191
+ // Performs outputAccum += weight0 * decoded(code0) + weight1 *
192
+ // decoded(code1)
193
+ static void accum(
194
+ const float* const __restrict pqCoarseCentroids,
195
+ const float* const __restrict pqFineCentroids,
196
+ const uint8_t* const __restrict code0,
197
+ const float weight0,
198
+ const uint8_t* const __restrict code1,
199
+ const float weight1,
200
+ float* const __restrict outputAccum) {
201
+ // coarse quantizer
202
+ const coarse_storage_type* const __restrict coarse0 =
203
+ reinterpret_cast<const coarse_storage_type*>(code0);
204
+ const coarse_storage_type* const __restrict coarse1 =
205
+ reinterpret_cast<const coarse_storage_type*>(code1);
206
+
207
+ // fine quantizer
208
+ const uint8_t* const __restrict fine0 =
209
+ code0 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
210
+ const uint8_t* const __restrict fine1 =
211
+ code1 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
212
+
213
+ #pragma unroll
214
+ for (intptr_t i = 0; i < DIM; i++) {
215
+ const intptr_t coarseCentroidIdx = i / COARSE_SIZE;
216
+ const intptr_t coarseCentroidOffset = i % COARSE_SIZE;
217
+ const intptr_t fineCentroidIdx = i / FINE_SIZE;
218
+ const intptr_t fineCentroidOffset = i % FINE_SIZE;
219
+
220
+ const intptr_t coarseCode0 = coarse0[coarseCentroidIdx];
221
+ const intptr_t fineCode0 = fine0[fineCentroidIdx];
222
+ const intptr_t coarseCode1 = coarse1[coarseCentroidIdx];
223
+ const intptr_t fineCode1 = fine1[fineCentroidIdx];
224
+
225
+ const float* const __restrict coarsePtr0 = pqCoarseCentroids +
226
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode0) *
227
+ COARSE_SIZE +
228
+ coarseCentroidOffset;
229
+ const float* const __restrict finePtr0 = pqFineCentroids +
230
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode0) *
231
+ FINE_SIZE +
232
+ fineCentroidOffset;
233
+ const float* const __restrict coarsePtr1 = pqCoarseCentroids +
234
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode1) *
235
+ COARSE_SIZE +
236
+ coarseCentroidOffset;
237
+ const float* const __restrict finePtr1 = pqFineCentroids +
238
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode1) *
239
+ FINE_SIZE +
240
+ fineCentroidOffset;
241
+
242
+ outputAccum[i] += weight0 * (*coarsePtr0 + *finePtr0) +
243
+ weight1 * (*coarsePtr1 + *finePtr1);
244
+ }
245
+ }
246
+
247
+ // Process 3 samples.
248
+ // Each code uses its own coarse pq centroids table and fine pq centroids
249
+ // table.
250
+ //
251
+ // Performs outputAccum += weight0 * decoded(code0) + weight1 *
252
+ // decoded(code1) + weight2 * decoded(code2)
253
+ static void accum(
254
+ const float* const __restrict pqCoarseCentroids0,
255
+ const float* const __restrict pqFineCentroids0,
256
+ const uint8_t* const __restrict code0,
257
+ const float weight0,
258
+ const float* const __restrict pqCoarseCentroids1,
259
+ const float* const __restrict pqFineCentroids1,
260
+ const uint8_t* const __restrict code1,
261
+ const float weight1,
262
+ const float* const __restrict pqCoarseCentroids2,
263
+ const float* const __restrict pqFineCentroids2,
264
+ const uint8_t* const __restrict code2,
265
+ const float weight2,
266
+ float* const __restrict outputAccum) {
267
+ // coarse quantizer
268
+ const coarse_storage_type* const __restrict coarse0 =
269
+ reinterpret_cast<const coarse_storage_type*>(code0);
270
+ const coarse_storage_type* const __restrict coarse1 =
271
+ reinterpret_cast<const coarse_storage_type*>(code1);
272
+ const coarse_storage_type* const __restrict coarse2 =
273
+ reinterpret_cast<const coarse_storage_type*>(code2);
274
+
275
+ // fine quantizer
276
+ const uint8_t* const __restrict fine0 =
277
+ code0 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
278
+ const uint8_t* const __restrict fine1 =
279
+ code1 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
280
+ const uint8_t* const __restrict fine2 =
281
+ code2 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
282
+
283
+ #pragma unroll
284
+ for (intptr_t i = 0; i < DIM; i++) {
285
+ const intptr_t coarseCentroidIdx = i / COARSE_SIZE;
286
+ const intptr_t coarseCentroidOffset = i % COARSE_SIZE;
287
+ const intptr_t fineCentroidIdx = i / FINE_SIZE;
288
+ const intptr_t fineCentroidOffset = i % FINE_SIZE;
289
+
290
+ const intptr_t coarseCode0 = coarse0[coarseCentroidIdx];
291
+ const intptr_t fineCode0 = fine0[fineCentroidIdx];
292
+ const intptr_t coarseCode1 = coarse1[coarseCentroidIdx];
293
+ const intptr_t fineCode1 = fine1[fineCentroidIdx];
294
+ const intptr_t coarseCode2 = coarse2[coarseCentroidIdx];
295
+ const intptr_t fineCode2 = fine2[fineCentroidIdx];
296
+
297
+ const float* const __restrict coarsePtr0 = pqCoarseCentroids0 +
298
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode0) *
299
+ COARSE_SIZE +
300
+ coarseCentroidOffset;
301
+ const float* const __restrict finePtr0 = pqFineCentroids0 +
302
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode0) *
303
+ FINE_SIZE +
304
+ fineCentroidOffset;
305
+ const float* const __restrict coarsePtr1 = pqCoarseCentroids1 +
306
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode1) *
307
+ COARSE_SIZE +
308
+ coarseCentroidOffset;
309
+ const float* const __restrict finePtr1 = pqFineCentroids1 +
310
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode1) *
311
+ FINE_SIZE +
312
+ fineCentroidOffset;
313
+ const float* const __restrict coarsePtr2 = pqCoarseCentroids2 +
314
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode2) *
315
+ COARSE_SIZE +
316
+ coarseCentroidOffset;
317
+ const float* const __restrict finePtr2 = pqFineCentroids2 +
318
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode2) *
319
+ FINE_SIZE +
320
+ fineCentroidOffset;
321
+
322
+ outputAccum[i] += weight0 * (*coarsePtr0 + *finePtr0) +
323
+ weight1 * (*coarsePtr1 + *finePtr1) +
324
+ weight2 * (*coarsePtr2 + *finePtr2);
325
+ }
326
+ }
327
+
328
+ // Process 3 samples.
329
+ // Coarse pq centroids table and fine pq centroids table are shared among
330
+ // codes.
331
+ //
332
+ // Performs outputAccum += weight0 * decoded(code0) + weight1 *
333
+ // decoded(code1) + weight2 * decoded(code2)
334
+ static void accum(
335
+ const float* const __restrict pqCoarseCentroids,
336
+ const float* const __restrict pqFineCentroids,
337
+ const uint8_t* const __restrict code0,
338
+ const float weight0,
339
+ const uint8_t* const __restrict code1,
340
+ const float weight1,
341
+ const uint8_t* const __restrict code2,
342
+ const float weight2,
343
+ float* const __restrict outputAccum) {
344
+ // coarse quantizer
345
+ const coarse_storage_type* const __restrict coarse0 =
346
+ reinterpret_cast<const coarse_storage_type*>(code0);
347
+ const coarse_storage_type* const __restrict coarse1 =
348
+ reinterpret_cast<const coarse_storage_type*>(code1);
349
+ const coarse_storage_type* const __restrict coarse2 =
350
+ reinterpret_cast<const coarse_storage_type*>(code2);
351
+
352
+ // fine quantizer
353
+ const uint8_t* const __restrict fine0 =
354
+ code0 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
355
+ const uint8_t* const __restrict fine1 =
356
+ code1 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
357
+ const uint8_t* const __restrict fine2 =
358
+ code2 + (DIM / COARSE_SIZE) * sizeof(coarse_storage_type);
359
+
360
+ #pragma unroll
361
+ for (intptr_t i = 0; i < DIM; i++) {
362
+ const intptr_t coarseCentroidIdx = i / COARSE_SIZE;
363
+ const intptr_t coarseCentroidOffset = i % COARSE_SIZE;
364
+ const intptr_t fineCentroidIdx = i / FINE_SIZE;
365
+ const intptr_t fineCentroidOffset = i % FINE_SIZE;
366
+
367
+ const intptr_t coarseCode0 = coarse0[coarseCentroidIdx];
368
+ const intptr_t fineCode0 = fine0[fineCentroidIdx];
369
+ const intptr_t coarseCode1 = coarse1[coarseCentroidIdx];
370
+ const intptr_t fineCode1 = fine1[fineCentroidIdx];
371
+ const intptr_t coarseCode2 = coarse2[coarseCentroidIdx];
372
+ const intptr_t fineCode2 = fine2[fineCentroidIdx];
373
+
374
+ const float* const __restrict coarsePtr0 = pqCoarseCentroids +
375
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode0) *
376
+ COARSE_SIZE +
377
+ coarseCentroidOffset;
378
+ const float* const __restrict finePtr0 = pqFineCentroids +
379
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode0) *
380
+ FINE_SIZE +
381
+ fineCentroidOffset;
382
+ const float* const __restrict coarsePtr1 = pqCoarseCentroids +
383
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode1) *
384
+ COARSE_SIZE +
385
+ coarseCentroidOffset;
386
+ const float* const __restrict finePtr1 = pqFineCentroids +
387
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode1) *
388
+ FINE_SIZE +
389
+ fineCentroidOffset;
390
+ const float* const __restrict coarsePtr2 = pqCoarseCentroids +
391
+ (coarseCentroidIdx * COARSE_TABLE_BYTES + coarseCode2) *
392
+ COARSE_SIZE +
393
+ coarseCentroidOffset;
394
+ const float* const __restrict finePtr2 = pqFineCentroids +
395
+ (fineCentroidIdx * FINE_TABLE_BYTES + fineCode2) *
396
+ FINE_SIZE +
397
+ fineCentroidOffset;
398
+
399
+ outputAccum[i] += weight0 * (*coarsePtr0 + *finePtr0) +
400
+ weight1 * (*coarsePtr1 + *finePtr1) +
401
+ weight2 * (*coarsePtr2 + *finePtr2);
402
+ }
403
+ }
404
+ };
405
+
406
+ } // namespace cppcontrib
407
+ } // namespace faiss
408
+ #endif // LEVEL2_INL_H