faiss 0.5.0 → 0.5.1

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +2 -0
  4. data/ext/faiss/index.cpp +8 -0
  5. data/lib/faiss/version.rb +1 -1
  6. data/vendor/faiss/faiss/IVFlib.cpp +25 -49
  7. data/vendor/faiss/faiss/Index.cpp +11 -0
  8. data/vendor/faiss/faiss/Index.h +24 -1
  9. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +1 -0
  10. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +5 -1
  11. data/vendor/faiss/faiss/IndexFastScan.cpp +1 -1
  12. data/vendor/faiss/faiss/IndexFastScan.h +3 -8
  13. data/vendor/faiss/faiss/IndexFlat.cpp +374 -4
  14. data/vendor/faiss/faiss/IndexFlat.h +80 -0
  15. data/vendor/faiss/faiss/IndexHNSW.cpp +90 -1
  16. data/vendor/faiss/faiss/IndexHNSW.h +57 -1
  17. data/vendor/faiss/faiss/IndexIVFFlatPanorama.cpp +34 -149
  18. data/vendor/faiss/faiss/IndexIVFRaBitQ.cpp +86 -2
  19. data/vendor/faiss/faiss/IndexIVFRaBitQ.h +3 -1
  20. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.cpp +293 -115
  21. data/vendor/faiss/faiss/IndexIVFRaBitQFastScan.h +52 -16
  22. data/vendor/faiss/faiss/IndexPQ.cpp +4 -1
  23. data/vendor/faiss/faiss/IndexPreTransform.cpp +14 -0
  24. data/vendor/faiss/faiss/IndexPreTransform.h +9 -0
  25. data/vendor/faiss/faiss/IndexRaBitQ.cpp +96 -16
  26. data/vendor/faiss/faiss/IndexRaBitQ.h +5 -1
  27. data/vendor/faiss/faiss/IndexRaBitQFastScan.cpp +238 -93
  28. data/vendor/faiss/faiss/IndexRaBitQFastScan.h +35 -9
  29. data/vendor/faiss/faiss/IndexRefine.cpp +49 -0
  30. data/vendor/faiss/faiss/IndexRefine.h +17 -0
  31. data/vendor/faiss/faiss/clone_index.cpp +2 -0
  32. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +3 -1
  33. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +1 -1
  34. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +1 -1
  35. data/vendor/faiss/faiss/impl/DistanceComputer.h +74 -3
  36. data/vendor/faiss/faiss/impl/HNSW.cpp +294 -15
  37. data/vendor/faiss/faiss/impl/HNSW.h +31 -2
  38. data/vendor/faiss/faiss/impl/IDSelector.h +3 -3
  39. data/vendor/faiss/faiss/impl/Panorama.cpp +193 -0
  40. data/vendor/faiss/faiss/impl/Panorama.h +204 -0
  41. data/vendor/faiss/faiss/impl/RaBitQStats.cpp +29 -0
  42. data/vendor/faiss/faiss/impl/RaBitQStats.h +56 -0
  43. data/vendor/faiss/faiss/impl/RaBitQUtils.cpp +54 -6
  44. data/vendor/faiss/faiss/impl/RaBitQUtils.h +183 -6
  45. data/vendor/faiss/faiss/impl/RaBitQuantizer.cpp +269 -84
  46. data/vendor/faiss/faiss/impl/RaBitQuantizer.h +71 -4
  47. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.cpp +362 -0
  48. data/vendor/faiss/faiss/impl/RaBitQuantizerMultiBit.h +112 -0
  49. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +6 -9
  50. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +1 -3
  51. data/vendor/faiss/faiss/impl/index_read.cpp +156 -12
  52. data/vendor/faiss/faiss/impl/index_write.cpp +142 -19
  53. data/vendor/faiss/faiss/impl/platform_macros.h +12 -0
  54. data/vendor/faiss/faiss/impl/svs_io.cpp +86 -0
  55. data/vendor/faiss/faiss/impl/svs_io.h +67 -0
  56. data/vendor/faiss/faiss/index_factory.cpp +182 -15
  57. data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +1 -1
  58. data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
  59. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +18 -109
  60. data/vendor/faiss/faiss/invlists/InvertedLists.h +2 -18
  61. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +1 -1
  62. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +1 -1
  63. data/vendor/faiss/faiss/svs/IndexSVSFaissUtils.h +261 -0
  64. data/vendor/faiss/faiss/svs/IndexSVSFlat.cpp +117 -0
  65. data/vendor/faiss/faiss/svs/IndexSVSFlat.h +66 -0
  66. data/vendor/faiss/faiss/svs/IndexSVSVamana.cpp +245 -0
  67. data/vendor/faiss/faiss/svs/IndexSVSVamana.h +137 -0
  68. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.cpp +39 -0
  69. data/vendor/faiss/faiss/svs/IndexSVSVamanaLVQ.h +42 -0
  70. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.cpp +149 -0
  71. data/vendor/faiss/faiss/svs/IndexSVSVamanaLeanVec.h +58 -0
  72. data/vendor/faiss/faiss/utils/distances.cpp +0 -3
  73. data/vendor/faiss/faiss/utils/utils.cpp +4 -0
  74. metadata +18 -1
@@ -16,16 +16,47 @@
16
16
  namespace faiss {
17
17
  namespace rabitq_utils {
18
18
 
19
- /** Factors computed per database vector for RaBitQ distance computation.
19
+ /** Base factors computed per database vector for RaBitQ distance computation.
20
+ * Used by both 1-bit and multi-bit RaBitQ variants.
20
21
  * These can be stored either embedded in codes (IndexRaBitQ) or separately
21
22
  * (IndexRaBitQFastScan).
23
+ *
24
+ * For 1-bit mode only - contains the minimal factors needed for distance
25
+ * estimation using just sign bits.
22
26
  */
23
- struct FactorsData {
27
+ FAISS_PACK_STRUCTS_BEGIN
28
+ struct FAISS_PACKED SignBitFactors {
24
29
  // ||or - c||^2 - ((metric==IP) ? ||or||^2 : 0)
25
30
  float or_minus_c_l2sqr = 0;
26
31
  float dp_multiplier = 0;
27
32
  };
28
33
 
34
+ /** Extended factors for multi-bit RaBitQ (nb_bits > 1).
35
+ * Includes error bound for lower bound computation in two-stage search.
36
+ * Inherits base factors to maintain layout compatibility.
37
+ *
38
+ * Used in multi-bit mode - the error bound enables quick filtering of
39
+ * unlikely candidates in the first stage of two-stage search.
40
+ */
41
+ struct FAISS_PACKED SignBitFactorsWithError : SignBitFactors {
42
+ // Error bound for lower bound computation in two-stage search
43
+ // Used in formula: lower_bound = est_distance - f_error * g_error
44
+ // Only allocated when nb_bits > 1
45
+ float f_error = 0;
46
+ };
47
+
48
+ /** Additional factors for multi-bit RaBitQ (nb_bits > 1).
49
+ * Used to store normalization and scaling factors for the refinement bits
50
+ * that encode additional precision beyond the sign bit.
51
+ */
52
+ struct FAISS_PACKED ExtraBitsFactors {
53
+ // Additive correction factor for refinement bit reconstruction
54
+ float f_add_ex = 0;
55
+ // Scaling/rescaling factor for refinement bit reconstruction
56
+ float f_rescale_ex = 0;
57
+ };
58
+ FAISS_PACK_STRUCTS_END
59
+
29
60
  /** Query-specific factors computed during search for RaBitQ distance
30
61
  * computation. Used by both IndexRaBitQ and IndexRaBitQFastScan
31
62
  * implementations.
@@ -39,6 +70,9 @@ struct QueryFactorsData {
39
70
  float qr_norm_L2sqr = 0;
40
71
 
41
72
  float int_dot_scale = 1;
73
+
74
+ float g_error = 0;
75
+ std::vector<float> rotated_q;
42
76
  };
43
77
 
44
78
  /** Ideal quantizer radii for quantizers of 1..8 bits, optimized to minimize
@@ -54,13 +88,15 @@ FAISS_API extern const float Z_MAX_BY_QB[8];
54
88
  * @param d dimensionality
55
89
  * @param centroid database centroid (nullptr if not used)
56
90
  * @param metric_type distance metric (L2 or Inner Product)
91
+ * @param compute_error whether to compute f_error (false for 1-bit mode)
57
92
  * @return computed factors for distance computation
58
93
  */
59
- FactorsData compute_vector_factors(
94
+ SignBitFactorsWithError compute_vector_factors(
60
95
  const float* x,
61
96
  size_t d,
62
97
  const float* centroid,
63
- MetricType metric_type);
98
+ MetricType metric_type,
99
+ bool compute_error = true);
64
100
 
65
101
  /** Compute intermediate values needed for vector factor computation.
66
102
  * Separated out to allow different bit packing strategies while sharing
@@ -87,14 +123,16 @@ void compute_vector_intermediate_values(
87
123
  * @param dp_oO sum of |or_i - c_i|
88
124
  * @param d dimensionality
89
125
  * @param metric_type distance metric
126
+ * @param compute_error whether to compute f_error (false for 1-bit mode)
90
127
  * @return computed factors
91
128
  */
92
- FactorsData compute_factors_from_intermediates(
129
+ SignBitFactorsWithError compute_factors_from_intermediates(
93
130
  float norm_L2sqr,
94
131
  float or_L2sqr,
95
132
  float dp_oO,
96
133
  size_t d,
97
- MetricType metric_type);
134
+ MetricType metric_type,
135
+ bool compute_error = true);
98
136
 
99
137
  /** Compute query factors for RaBitQ distance computation.
100
138
  * This consolidates the query processing logic shared between implementations.
@@ -149,5 +187,144 @@ void set_bit_standard(uint8_t* code, size_t bit_index);
149
187
  */
150
188
  void set_bit_fastscan(uint8_t* code, size_t bit_index);
151
189
 
190
+ /** Compute adjusted 1-bit distance from normalized LUT distance.
191
+ * This is the core distance formula shared by all RaBitQ handlers.
192
+ *
193
+ * @param normalized_distance Distance from SIMD LUT lookup (after
194
+ * normalization)
195
+ * @param db_factors Database vector factors (SignBitFactors or
196
+ * SignBitFactorsWithError)
197
+ * @param query_factors Query factors computed during search
198
+ * @param centered Whether centered quantization is used
199
+ * @param qb Number of quantization bits
200
+ * @param d Dimensionality
201
+ * @return Adjusted distance value
202
+ */
203
+ inline float compute_1bit_adjusted_distance(
204
+ float normalized_distance,
205
+ const SignBitFactors& db_factors,
206
+ const QueryFactorsData& query_factors,
207
+ bool centered,
208
+ size_t qb,
209
+ size_t d) {
210
+ float adjusted_distance;
211
+
212
+ if (centered) {
213
+ // For centered mode: normalized_distance contains the raw XOR
214
+ // contribution. Apply the signed odd integer quantization formula:
215
+ // int_dot = ((1 << qb) - 1) * d - 2 * xor_dot_product
216
+ int64_t int_dot = ((1 << qb) - 1) * d;
217
+ int_dot -= 2 * static_cast<int64_t>(normalized_distance);
218
+
219
+ adjusted_distance = query_factors.qr_to_c_L2sqr +
220
+ db_factors.or_minus_c_l2sqr -
221
+ 2 * db_factors.dp_multiplier * int_dot *
222
+ query_factors.int_dot_scale;
223
+ } else {
224
+ // For non-centered quantization: use traditional formula
225
+ float final_dot = normalized_distance - query_factors.c34;
226
+ adjusted_distance = db_factors.or_minus_c_l2sqr +
227
+ query_factors.qr_to_c_L2sqr -
228
+ 2 * db_factors.dp_multiplier * final_dot;
229
+ }
230
+
231
+ // Apply inner product correction if needed
232
+ if (query_factors.qr_norm_L2sqr != 0.0f) {
233
+ adjusted_distance =
234
+ -0.5f * (adjusted_distance - query_factors.qr_norm_L2sqr);
235
+ } else {
236
+ adjusted_distance = std::max(0.0f, adjusted_distance);
237
+ }
238
+
239
+ return adjusted_distance;
240
+ }
241
+
242
+ /** Extract multi-bit code on-the-fly from packed ex-bit codes.
243
+ * This inline function extracts a single code value without unpacking the
244
+ * entire array, enabling efficient on-the-fly decoding during distance
245
+ * computation.
246
+ *
247
+ * @param ex_code packed ex-bit codes
248
+ * @param index which code to extract (0 to d-1)
249
+ * @param ex_bits number of bits per code (1-8)
250
+ * @return extracted code value in range [0, 2^ex_bits - 1]
251
+ */
252
+ inline int extract_code_inline(
253
+ const uint8_t* ex_code,
254
+ size_t index,
255
+ size_t ex_bits) {
256
+ size_t bit_pos = index * ex_bits;
257
+ int code_value = 0;
258
+
259
+ // Extract ex_bits bits starting at bit_pos
260
+ for (size_t bit = 0; bit < ex_bits; bit++) {
261
+ size_t byte_idx = bit_pos / 8;
262
+ size_t bit_idx = bit_pos % 8;
263
+
264
+ if (ex_code[byte_idx] & (1 << bit_idx)) {
265
+ code_value |= (1 << bit);
266
+ }
267
+
268
+ bit_pos++;
269
+ }
270
+
271
+ return code_value;
272
+ }
273
+
274
+ /** Compute full multi-bit distance from sign bits and ex-bit codes.
275
+ * This is the core distance computation shared by RaBitQFastScan handlers.
276
+ *
277
+ * The multi-bit distance combines the sign bit (1-bit) with additional
278
+ * magnitude bits (ex_bits) to compute a more accurate distance estimate.
279
+ *
280
+ * @param sign_bits unpacked sign bits (1-bit codes in standard format)
281
+ * @param ex_code packed ex-bit codes
282
+ * @param ex_fac ex-bit factors (f_add_ex, f_rescale_ex)
283
+ * @param rotated_q rotated query vector
284
+ * @param qr_to_c_L2sqr precomputed ||query_rotated - centroid||^2
285
+ * @param qr_norm_L2sqr precomputed ||query_rotated||^2 (0 for L2 metric)
286
+ * @param d dimensionality
287
+ * @param ex_bits number of extra bits (nb_bits - 1)
288
+ * @param metric_type distance metric (L2 or Inner Product)
289
+ * @return computed full multi-bit distance
290
+ */
291
+ inline float compute_full_multibit_distance(
292
+ const uint8_t* sign_bits,
293
+ const uint8_t* ex_code,
294
+ const ExtraBitsFactors& ex_fac,
295
+ const float* rotated_q,
296
+ float qr_to_c_L2sqr,
297
+ float qr_norm_L2sqr,
298
+ size_t d,
299
+ size_t ex_bits,
300
+ MetricType metric_type) {
301
+ float ex_ip = 0.0f;
302
+ const float cb = -(static_cast<float>(1 << ex_bits) - 0.5f);
303
+
304
+ for (size_t i = 0; i < d; i++) {
305
+ const size_t byte_idx = i / 8;
306
+ const size_t bit_offset = i % 8;
307
+ const bool sign_bit = (sign_bits[byte_idx] >> bit_offset) & 1;
308
+
309
+ int ex_code_val = extract_code_inline(ex_code, i, ex_bits);
310
+
311
+ int total_code = (sign_bit ? 1 : 0) << ex_bits;
312
+ total_code += ex_code_val;
313
+ float reconstructed = static_cast<float>(total_code) + cb;
314
+
315
+ ex_ip += rotated_q[i] * reconstructed;
316
+ }
317
+
318
+ float dist = qr_to_c_L2sqr + ex_fac.f_add_ex + ex_fac.f_rescale_ex * ex_ip;
319
+
320
+ if (metric_type == MetricType::METRIC_INNER_PRODUCT) {
321
+ dist = -0.5f * (dist - qr_norm_L2sqr);
322
+ } else {
323
+ dist = std::max(0.0f, dist);
324
+ }
325
+
326
+ return dist;
327
+ }
328
+
152
329
  } // namespace rabitq_utils
153
330
  } // namespace faiss