faiss 0.1.4 → 0.2.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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -1
  3. data/README.md +15 -3
  4. data/ext/faiss/ext.cpp +12 -308
  5. data/ext/faiss/extconf.rb +5 -2
  6. data/ext/faiss/index.cpp +189 -0
  7. data/ext/faiss/index_binary.cpp +75 -0
  8. data/ext/faiss/kmeans.cpp +40 -0
  9. data/ext/faiss/numo.hpp +867 -0
  10. data/ext/faiss/pca_matrix.cpp +33 -0
  11. data/ext/faiss/product_quantizer.cpp +53 -0
  12. data/ext/faiss/utils.cpp +13 -0
  13. data/ext/faiss/utils.h +5 -0
  14. data/lib/faiss.rb +0 -5
  15. data/lib/faiss/version.rb +1 -1
  16. data/vendor/faiss/faiss/AutoTune.cpp +292 -291
  17. data/vendor/faiss/faiss/AutoTune.h +55 -56
  18. data/vendor/faiss/faiss/Clustering.cpp +334 -195
  19. data/vendor/faiss/faiss/Clustering.h +88 -35
  20. data/vendor/faiss/faiss/IVFlib.cpp +171 -195
  21. data/vendor/faiss/faiss/IVFlib.h +48 -51
  22. data/vendor/faiss/faiss/Index.cpp +85 -103
  23. data/vendor/faiss/faiss/Index.h +54 -48
  24. data/vendor/faiss/faiss/Index2Layer.cpp +139 -164
  25. data/vendor/faiss/faiss/Index2Layer.h +22 -22
  26. data/vendor/faiss/faiss/IndexBinary.cpp +45 -37
  27. data/vendor/faiss/faiss/IndexBinary.h +140 -132
  28. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +73 -53
  29. data/vendor/faiss/faiss/IndexBinaryFlat.h +29 -24
  30. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +46 -43
  31. data/vendor/faiss/faiss/IndexBinaryFromFloat.h +16 -15
  32. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +215 -232
  33. data/vendor/faiss/faiss/IndexBinaryHNSW.h +25 -24
  34. data/vendor/faiss/faiss/IndexBinaryHash.cpp +182 -177
  35. data/vendor/faiss/faiss/IndexBinaryHash.h +41 -34
  36. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +489 -461
  37. data/vendor/faiss/faiss/IndexBinaryIVF.h +97 -68
  38. data/vendor/faiss/faiss/IndexFlat.cpp +116 -147
  39. data/vendor/faiss/faiss/IndexFlat.h +35 -46
  40. data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
  41. data/vendor/faiss/faiss/IndexHNSW.h +57 -41
  42. data/vendor/faiss/faiss/IndexIVF.cpp +474 -454
  43. data/vendor/faiss/faiss/IndexIVF.h +146 -113
  44. data/vendor/faiss/faiss/IndexIVFFlat.cpp +248 -250
  45. data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
  46. data/vendor/faiss/faiss/IndexIVFPQ.cpp +457 -516
  47. data/vendor/faiss/faiss/IndexIVFPQ.h +74 -66
  48. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +406 -372
  49. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +82 -57
  50. data/vendor/faiss/faiss/IndexIVFPQR.cpp +104 -102
  51. data/vendor/faiss/faiss/IndexIVFPQR.h +33 -28
  52. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +125 -133
  53. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +19 -21
  54. data/vendor/faiss/faiss/IndexLSH.cpp +75 -96
  55. data/vendor/faiss/faiss/IndexLSH.h +21 -26
  56. data/vendor/faiss/faiss/IndexLattice.cpp +42 -56
  57. data/vendor/faiss/faiss/IndexLattice.h +11 -16
  58. data/vendor/faiss/faiss/IndexNNDescent.cpp +231 -0
  59. data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
  60. data/vendor/faiss/faiss/IndexNSG.cpp +303 -0
  61. data/vendor/faiss/faiss/IndexNSG.h +85 -0
  62. data/vendor/faiss/faiss/IndexPQ.cpp +405 -464
  63. data/vendor/faiss/faiss/IndexPQ.h +64 -67
  64. data/vendor/faiss/faiss/IndexPQFastScan.cpp +143 -170
  65. data/vendor/faiss/faiss/IndexPQFastScan.h +46 -32
  66. data/vendor/faiss/faiss/IndexPreTransform.cpp +120 -150
  67. data/vendor/faiss/faiss/IndexPreTransform.h +33 -36
  68. data/vendor/faiss/faiss/IndexRefine.cpp +115 -131
  69. data/vendor/faiss/faiss/IndexRefine.h +22 -23
  70. data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
  71. data/vendor/faiss/faiss/IndexReplicas.h +62 -56
  72. data/vendor/faiss/faiss/IndexResidual.cpp +291 -0
  73. data/vendor/faiss/faiss/IndexResidual.h +152 -0
  74. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +120 -155
  75. data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -45
  76. data/vendor/faiss/faiss/IndexShards.cpp +256 -240
  77. data/vendor/faiss/faiss/IndexShards.h +85 -73
  78. data/vendor/faiss/faiss/MatrixStats.cpp +112 -97
  79. data/vendor/faiss/faiss/MatrixStats.h +7 -10
  80. data/vendor/faiss/faiss/MetaIndexes.cpp +135 -157
  81. data/vendor/faiss/faiss/MetaIndexes.h +40 -34
  82. data/vendor/faiss/faiss/MetricType.h +7 -7
  83. data/vendor/faiss/faiss/VectorTransform.cpp +652 -474
  84. data/vendor/faiss/faiss/VectorTransform.h +61 -89
  85. data/vendor/faiss/faiss/clone_index.cpp +77 -73
  86. data/vendor/faiss/faiss/clone_index.h +4 -9
  87. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +33 -38
  88. data/vendor/faiss/faiss/gpu/GpuAutoTune.h +11 -9
  89. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +197 -170
  90. data/vendor/faiss/faiss/gpu/GpuCloner.h +53 -35
  91. data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +12 -14
  92. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +27 -25
  93. data/vendor/faiss/faiss/gpu/GpuDistance.h +116 -112
  94. data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -2
  95. data/vendor/faiss/faiss/gpu/GpuIndex.h +134 -137
  96. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +76 -73
  97. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +173 -162
  98. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +67 -64
  99. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +89 -86
  100. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +150 -141
  101. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +101 -103
  102. data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +17 -16
  103. data/vendor/faiss/faiss/gpu/GpuResources.cpp +116 -128
  104. data/vendor/faiss/faiss/gpu/GpuResources.h +182 -186
  105. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +433 -422
  106. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +131 -130
  107. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +468 -456
  108. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +25 -19
  109. data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +22 -20
  110. data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +9 -8
  111. data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +39 -44
  112. data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +16 -14
  113. data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +77 -71
  114. data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +109 -88
  115. data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +75 -64
  116. data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +230 -215
  117. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +80 -86
  118. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +284 -277
  119. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +416 -416
  120. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +611 -517
  121. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +166 -164
  122. data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +61 -53
  123. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +274 -238
  124. data/vendor/faiss/faiss/gpu/test/TestUtils.h +73 -57
  125. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +47 -50
  126. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +79 -72
  127. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +140 -146
  128. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +69 -71
  129. data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +21 -16
  130. data/vendor/faiss/faiss/gpu/utils/Timer.cpp +25 -29
  131. data/vendor/faiss/faiss/gpu/utils/Timer.h +30 -29
  132. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +270 -0
  133. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +115 -0
  134. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +90 -120
  135. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +81 -65
  136. data/vendor/faiss/faiss/impl/FaissAssert.h +73 -58
  137. data/vendor/faiss/faiss/impl/FaissException.cpp +56 -48
  138. data/vendor/faiss/faiss/impl/FaissException.h +41 -29
  139. data/vendor/faiss/faiss/impl/HNSW.cpp +595 -611
  140. data/vendor/faiss/faiss/impl/HNSW.h +179 -200
  141. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +672 -0
  142. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +172 -0
  143. data/vendor/faiss/faiss/impl/NNDescent.cpp +487 -0
  144. data/vendor/faiss/faiss/impl/NNDescent.h +154 -0
  145. data/vendor/faiss/faiss/impl/NSG.cpp +682 -0
  146. data/vendor/faiss/faiss/impl/NSG.h +199 -0
  147. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +484 -454
  148. data/vendor/faiss/faiss/impl/PolysemousTraining.h +52 -55
  149. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +26 -47
  150. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +469 -459
  151. data/vendor/faiss/faiss/impl/ProductQuantizer.h +76 -87
  152. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +448 -0
  153. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +130 -0
  154. data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
  155. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +648 -701
  156. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +48 -46
  157. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +129 -131
  158. data/vendor/faiss/faiss/impl/ThreadedIndex.h +61 -55
  159. data/vendor/faiss/faiss/impl/index_read.cpp +547 -479
  160. data/vendor/faiss/faiss/impl/index_write.cpp +497 -407
  161. data/vendor/faiss/faiss/impl/io.cpp +75 -94
  162. data/vendor/faiss/faiss/impl/io.h +31 -41
  163. data/vendor/faiss/faiss/impl/io_macros.h +40 -29
  164. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +137 -186
  165. data/vendor/faiss/faiss/impl/lattice_Zn.h +40 -51
  166. data/vendor/faiss/faiss/impl/platform_macros.h +29 -8
  167. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +77 -124
  168. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +39 -48
  169. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +41 -52
  170. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +80 -117
  171. data/vendor/faiss/faiss/impl/simd_result_handlers.h +109 -137
  172. data/vendor/faiss/faiss/index_factory.cpp +269 -218
  173. data/vendor/faiss/faiss/index_factory.h +6 -7
  174. data/vendor/faiss/faiss/index_io.h +23 -26
  175. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +67 -75
  176. data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +22 -24
  177. data/vendor/faiss/faiss/invlists/DirectMap.cpp +96 -112
  178. data/vendor/faiss/faiss/invlists/DirectMap.h +29 -33
  179. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +307 -364
  180. data/vendor/faiss/faiss/invlists/InvertedLists.h +151 -151
  181. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +29 -34
  182. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +17 -18
  183. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +257 -293
  184. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +50 -45
  185. data/vendor/faiss/faiss/python/python_callbacks.cpp +23 -26
  186. data/vendor/faiss/faiss/python/python_callbacks.h +9 -16
  187. data/vendor/faiss/faiss/utils/AlignedTable.h +79 -44
  188. data/vendor/faiss/faiss/utils/Heap.cpp +40 -48
  189. data/vendor/faiss/faiss/utils/Heap.h +186 -209
  190. data/vendor/faiss/faiss/utils/WorkerThread.cpp +67 -76
  191. data/vendor/faiss/faiss/utils/WorkerThread.h +32 -33
  192. data/vendor/faiss/faiss/utils/distances.cpp +301 -310
  193. data/vendor/faiss/faiss/utils/distances.h +133 -118
  194. data/vendor/faiss/faiss/utils/distances_simd.cpp +456 -516
  195. data/vendor/faiss/faiss/utils/extra_distances-inl.h +117 -0
  196. data/vendor/faiss/faiss/utils/extra_distances.cpp +113 -232
  197. data/vendor/faiss/faiss/utils/extra_distances.h +30 -29
  198. data/vendor/faiss/faiss/utils/hamming-inl.h +260 -209
  199. data/vendor/faiss/faiss/utils/hamming.cpp +375 -469
  200. data/vendor/faiss/faiss/utils/hamming.h +62 -85
  201. data/vendor/faiss/faiss/utils/ordered_key_value.h +16 -18
  202. data/vendor/faiss/faiss/utils/partitioning.cpp +393 -318
  203. data/vendor/faiss/faiss/utils/partitioning.h +26 -21
  204. data/vendor/faiss/faiss/utils/quantize_lut.cpp +78 -66
  205. data/vendor/faiss/faiss/utils/quantize_lut.h +22 -20
  206. data/vendor/faiss/faiss/utils/random.cpp +39 -63
  207. data/vendor/faiss/faiss/utils/random.h +13 -16
  208. data/vendor/faiss/faiss/utils/simdlib.h +4 -2
  209. data/vendor/faiss/faiss/utils/simdlib_avx2.h +88 -85
  210. data/vendor/faiss/faiss/utils/simdlib_emulated.h +226 -165
  211. data/vendor/faiss/faiss/utils/simdlib_neon.h +832 -0
  212. data/vendor/faiss/faiss/utils/utils.cpp +304 -287
  213. data/vendor/faiss/faiss/utils/utils.h +53 -48
  214. metadata +31 -10
  215. data/lib/faiss/index.rb +0 -20
  216. data/lib/faiss/index_binary.rb +0 -20
  217. data/lib/faiss/kmeans.rb +0 -15
  218. data/lib/faiss/pca_matrix.rb +0 -15
  219. data/lib/faiss/product_quantizer.rb +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4541b0c40468723a8bed3db80d5778fb156afa999cbbd14b83653285b3ae6267
4
- data.tar.gz: 2beeacbad82a578e2a410938bc4447d73699ef3998c146b4309e4b44816f5e33
3
+ metadata.gz: 6ee0d4a001e68d64f406740bab3bb62f8f2813f8f58e6c9ea93261514cfaec47
4
+ data.tar.gz: a5ddc48f022b0d9b72499766af6f3eaa52c4a36cb2a21d72b333654795539799
5
5
  SHA512:
6
- metadata.gz: 92d87492ff627e094ef29a48c8e4579dd976846ec9a95d94c45b816391dcea332d370a5fbde9c3f2bdc11964e061557d0e150b223ab6ac0209c092f1e1cd4a6e
7
- data.tar.gz: 86fc2aaf3151545f24128429cf1369074809f8449f277a2676e9dacea76c156191b3d6df6df83f0d7ac0f061bfdf537b81ef57f6cbbb861e4ba4b592d06e8ca2
6
+ metadata.gz: 242636e52ae8fb025cf212fd41e3d27c06d17e05eb59469dd400ab8cf5412e61a1b88d582e0ea188985f3281a90eac0dd2b0ecbefb957864600cda22d9b3900a
7
+ data.tar.gz: 503c4da4a25fa905ef108e564ac715030aa9d10f2df5b1b80a35da99020c11eda3b8ed4ab067324f0d2029b0b90e7ce65d330343ee49d6761c4d98b0fb27655e
data/CHANGELOG.md CHANGED
@@ -1,4 +1,29 @@
1
- ## 0.1.4 (2020-02-04)
1
+ ## 0.2.1 (2021-06-07)
2
+
3
+ - Updated Faiss to 1.7.1
4
+
5
+ ## 0.2.0 (2021-05-23)
6
+
7
+ - Improved performance
8
+ - Updated to Rice 4
9
+ - Dropped support for Ruby < 2.6
10
+
11
+ ## 0.1.7 (2021-03-26)
12
+
13
+ - Added `IndexScalarQuantizer` and `IndexIVFScalarQuantizer`
14
+
15
+ ## 0.1.6 (2021-03-21)
16
+
17
+ - Added support for inner product to `IndexIVFFlat` and `IndexIVFPQ`
18
+ - Added `ParameterSpace`
19
+ - Added `nprobe=` method
20
+
21
+ ## 0.1.5 (2021-03-14)
22
+
23
+ - Added `--with-optflags` option
24
+ - Added support for inner product to `IndexHNSWFlat`
25
+
26
+ ## 0.1.4 (2021-02-04)
2
27
 
3
28
  - Updated Faiss to 1.7.0
4
29
 
data/README.md CHANGED
@@ -24,7 +24,7 @@ Add this line to your application’s Gemfile:
24
24
  gem 'faiss'
25
25
  ```
26
26
 
27
- Faiss is not available for Windows
27
+ It can take a few minutes to compile the gem. Faiss is not available for Windows.
28
28
 
29
29
  ## Getting Started
30
30
 
@@ -97,12 +97,24 @@ Locality-sensitive hashing
97
97
  Faiss::IndexLSH.new(d, nbits)
98
98
  ```
99
99
 
100
+ Scalar quantizer (SQ) in flat mode
101
+
102
+ ```rb
103
+ Faiss::IndexScalarQuantizer.new(d, qtype)
104
+ ```
105
+
100
106
  Product quantizer (PQ) in flat mode
101
107
 
102
108
  ```rb
103
109
  Faiss::IndexPQ.new(d, m, nbits)
104
110
  ```
105
111
 
112
+ IVF and scalar quantizer
113
+
114
+ ```rb
115
+ Faiss::IndexIVFScalarQuantizer.new(quantizer, d, nlists, qtype)
116
+ ```
117
+
106
118
  IVFADC (coarse quantizer+PQ on residuals)
107
119
 
108
120
  ```rb
@@ -200,10 +212,10 @@ Data can be an array of arrays
200
212
  [[1, 2, 3], [4, 5, 6]]
201
213
  ```
202
214
 
203
- Or a Numo NArray
215
+ Or a Numo array
204
216
 
205
217
  ```ruby
206
- Numo::SFloat.new(3, 2).seq
218
+ Numo::NArray.cast([[1, 2, 3], [4, 5, 6]])
207
219
  ```
208
220
 
209
221
  ## History
data/ext/faiss/ext.cpp CHANGED
@@ -1,315 +1,19 @@
1
- #include <faiss/IndexFlat.h>
2
- #include <faiss/IndexHNSW.h>
3
- #include <faiss/IndexIVFFlat.h>
4
- #include <faiss/IndexLSH.h>
5
- #include <faiss/IndexScalarQuantizer.h>
6
- #include <faiss/IndexPQ.h>
7
- #include <faiss/IndexIVFPQ.h>
8
- #include <faiss/IndexIVFPQR.h>
1
+ #include "utils.h"
9
2
 
10
- #include <faiss/IndexBinaryFlat.h>
11
- #include <faiss/IndexBinaryIVF.h>
12
- #include <faiss/index_factory.h>
13
- #include <faiss/index_io.h>
14
-
15
- #include <faiss/Clustering.h>
16
- #include <faiss/VectorTransform.h>
17
-
18
- #include <rice/Array.hpp>
19
- #include <rice/Class.hpp>
20
- #include <rice/Constructor.hpp>
21
- #include <rice/Module.hpp>
22
-
23
- float* float_array(Rice::Object o)
24
- {
25
- Rice::String s = o.call("to_binary");
26
- return (float*) s.c_str();
27
- }
28
-
29
- uint8_t* uint8_array(Rice::Object o)
30
- {
31
- Rice::String s = o.call("to_binary");
32
- return (uint8_t*) s.c_str();
33
- }
34
-
35
- // TODO return Numo::SFloat
36
- Rice::String result(float* ptr, int64_t length)
37
- {
38
- return Rice::String(std::string((char*) ptr, length * sizeof(float)));
39
- }
40
-
41
- // TODO return Numo::UInt8
42
- Rice::String result(uint8_t* ptr, int64_t length)
43
- {
44
- return Rice::String(std::string((char*) ptr, length * sizeof(uint8_t)));
45
- }
46
-
47
- // TODO return Numo::Int32
48
- Rice::String result(int32_t* ptr, int64_t length)
49
- {
50
- return Rice::String(std::string((char*) ptr, length * sizeof(int32_t)));
51
- }
52
-
53
- // TODO return Numo::Int64
54
- Rice::String result(int64_t* ptr, int64_t length)
55
- {
56
- return Rice::String(std::string((char*) ptr, length * sizeof(int64_t)));
57
- }
3
+ void init_index(Rice::Module& m);
4
+ void init_index_binary(Rice::Module& m);
5
+ void init_kmeans(Rice::Module& m);
6
+ void init_pca_matrix(Rice::Module& m);
7
+ void init_product_quantizer(Rice::Module& m);
58
8
 
59
9
  extern "C"
60
10
  void Init_ext()
61
11
  {
62
- Rice::Module rb_mFaiss = Rice::define_module("Faiss")
63
- .define_singleton_method(
64
- "index_binary_factory",
65
- *[](int d, const char *description) {
66
- return faiss::index_binary_factory(d, description);
67
- });
68
-
69
- Rice::define_class_under<faiss::Index>(rb_mFaiss, "Index")
70
- .define_method(
71
- "d",
72
- *[](faiss::Index &self) {
73
- return self.d;
74
- })
75
- .define_method(
76
- "trained?",
77
- *[](faiss::Index &self) {
78
- return self.is_trained;
79
- })
80
- .define_method(
81
- "ntotal",
82
- *[](faiss::Index &self) {
83
- return self.ntotal;
84
- })
85
- .define_method(
86
- "_train",
87
- *[](faiss::Index &self, int64_t n, Rice::Object o) {
88
- const float *x = float_array(o);
89
- self.train(n, x);
90
- })
91
- .define_method(
92
- "_add",
93
- *[](faiss::Index &self, int64_t n, Rice::Object o) {
94
- const float *x = float_array(o);
95
- self.add(n, x);
96
- })
97
- .define_method(
98
- "_search",
99
- *[](faiss::Index &self, int64_t n, Rice::Object o, int64_t k) {
100
- const float *x = float_array(o);
101
- float *distances = new float[k * n];
102
- int64_t *labels = new int64_t[k * n];
103
-
104
- self.search(n, x, k, distances, labels);
105
-
106
- auto dstr = result(distances, k * n);
107
- auto lstr = result(labels, k * n);
108
-
109
- Rice::Array ret;
110
- ret.push(dstr);
111
- ret.push(lstr);
112
- return ret;
113
- })
114
- .define_method(
115
- "save",
116
- *[](faiss::Index &self, const char *fname) {
117
- faiss::write_index(&self, fname);
118
- })
119
- .define_singleton_method(
120
- "load",
121
- *[](const char *fname) {
122
- return faiss::read_index(fname);
123
- });
124
-
125
- Rice::define_class_under<faiss::IndexBinary>(rb_mFaiss, "IndexBinary")
126
- .define_method(
127
- "d",
128
- *[](faiss::Index &self) {
129
- return self.d;
130
- })
131
- .define_method(
132
- "trained?",
133
- *[](faiss::IndexBinary &self) {
134
- return self.is_trained;
135
- })
136
- .define_method(
137
- "ntotal",
138
- *[](faiss::IndexBinary &self) {
139
- return self.ntotal;
140
- })
141
- .define_method(
142
- "_train",
143
- *[](faiss::IndexBinary &self, int64_t n, Rice::Object o) {
144
- const uint8_t *x = uint8_array(o);
145
- self.train(n, x);
146
- })
147
- .define_method(
148
- "_add",
149
- *[](faiss::IndexBinary &self, int64_t n, Rice::Object o) {
150
- const uint8_t *x = uint8_array(o);
151
- self.add(n, x);
152
- })
153
- .define_method(
154
- "_search",
155
- *[](faiss::IndexBinary &self, int64_t n, Rice::Object o, int64_t k) {
156
- const uint8_t *x = uint8_array(o);
157
- int32_t *distances = new int32_t[k * n];
158
- int64_t *labels = new int64_t[k * n];
159
-
160
- self.search(n, x, k, distances, labels);
161
-
162
- auto dstr = result(distances, k * n);
163
- auto lstr = result(labels, k * n);
164
-
165
- Rice::Array ret;
166
- ret.push(dstr);
167
- ret.push(lstr);
168
- return ret;
169
- })
170
- .define_method(
171
- "save",
172
- *[](faiss::IndexBinary &self, const char *fname) {
173
- faiss::write_index_binary(&self, fname);
174
- })
175
- .define_singleton_method(
176
- "load",
177
- *[](const char *fname) {
178
- return faiss::read_index_binary(fname);
179
- });
180
-
181
- Rice::define_class_under<faiss::IndexFlatL2, faiss::Index>(rb_mFaiss, "IndexFlatL2")
182
- .define_constructor(Rice::Constructor<faiss::IndexFlatL2, int64_t>());
183
-
184
- Rice::define_class_under<faiss::IndexFlatIP, faiss::Index>(rb_mFaiss, "IndexFlatIP")
185
- .define_constructor(Rice::Constructor<faiss::IndexFlatIP, int64_t>());
186
-
187
- Rice::define_class_under<faiss::IndexHNSWFlat, faiss::Index>(rb_mFaiss, "IndexHNSWFlat")
188
- .define_constructor(Rice::Constructor<faiss::IndexHNSWFlat, int, int>());
189
-
190
- Rice::define_class_under<faiss::IndexIVFFlat, faiss::Index>(rb_mFaiss, "IndexIVFFlat")
191
- .define_constructor(Rice::Constructor<faiss::IndexIVFFlat, faiss::Index*, size_t, size_t>());
192
-
193
- Rice::define_class_under<faiss::IndexLSH, faiss::Index>(rb_mFaiss, "IndexLSH")
194
- .define_constructor(Rice::Constructor<faiss::IndexLSH, int64_t, int>());
195
-
196
- Rice::define_class_under<faiss::IndexScalarQuantizer, faiss::Index>(rb_mFaiss, "IndexScalarQuantizer")
197
- .define_constructor(Rice::Constructor<faiss::IndexScalarQuantizer, int, faiss::ScalarQuantizer::QuantizerType>());
198
-
199
- Rice::define_class_under<faiss::IndexPQ, faiss::Index>(rb_mFaiss, "IndexPQ")
200
- .define_constructor(Rice::Constructor<faiss::IndexPQ, int, size_t, size_t>());
201
-
202
- Rice::define_class_under<faiss::IndexIVFScalarQuantizer, faiss::Index>(rb_mFaiss, "IndexIVFScalarQuantizer")
203
- .define_constructor(Rice::Constructor<faiss::IndexIVFScalarQuantizer, faiss::Index*, size_t, size_t, faiss::ScalarQuantizer::QuantizerType>());
204
-
205
- Rice::define_class_under<faiss::IndexIVFPQ, faiss::Index>(rb_mFaiss, "IndexIVFPQ")
206
- .define_constructor(Rice::Constructor<faiss::IndexIVFPQ, faiss::Index*, size_t, size_t, size_t, size_t>());
207
-
208
- Rice::define_class_under<faiss::IndexIVFPQR, faiss::Index>(rb_mFaiss, "IndexIVFPQR")
209
- .define_constructor(Rice::Constructor<faiss::IndexIVFPQR, faiss::Index*, size_t, size_t, size_t, size_t, size_t, size_t>());
210
-
211
- Rice::define_class_under<faiss::IndexBinaryFlat, faiss::IndexBinary>(rb_mFaiss, "IndexBinaryFlat")
212
- .define_constructor(Rice::Constructor<faiss::IndexBinaryFlat, int64_t>());
213
-
214
- Rice::define_class_under<faiss::IndexBinaryIVF, faiss::IndexBinary>(rb_mFaiss, "IndexBinaryIVF")
215
- .define_constructor(Rice::Constructor<faiss::IndexBinaryIVF, faiss::IndexBinary*, size_t, size_t>());
216
-
217
- Rice::define_class_under<faiss::Clustering>(rb_mFaiss, "Kmeans")
218
- .define_constructor(Rice::Constructor<faiss::Clustering, int, int>())
219
- .define_method(
220
- "d",
221
- *[](faiss::Clustering &self) {
222
- return self.d;
223
- })
224
- .define_method(
225
- "k",
226
- *[](faiss::Clustering &self) {
227
- return self.k;
228
- })
229
- .define_method(
230
- "_centroids",
231
- *[](faiss::Clustering &self) {
232
- float *centroids = new float[self.k * self.d];
233
- for (size_t i = 0; i < self.centroids.size(); i++) {
234
- centroids[i] = self.centroids[i];
235
- }
236
- return result(centroids, self.k * self.d);
237
- })
238
- .define_method(
239
- "_train",
240
- *[](faiss::Clustering &self, int64_t n, Rice::Object o, faiss::Index & index) {
241
- const float *x = float_array(o);
242
- self.train(n, x, index);
243
- });
244
-
245
- Rice::define_class_under<faiss::PCAMatrix>(rb_mFaiss, "PCAMatrix")
246
- .define_constructor(Rice::Constructor<faiss::PCAMatrix, int, int>())
247
- .define_method(
248
- "d_in",
249
- *[](faiss::PCAMatrix &self) {
250
- return self.d_in;
251
- })
252
- .define_method(
253
- "d_out",
254
- *[](faiss::PCAMatrix &self) {
255
- return self.d_out;
256
- })
257
- .define_method(
258
- "_train",
259
- *[](faiss::PCAMatrix &self, int64_t n, Rice::Object o) {
260
- const float *x = float_array(o);
261
- self.train(n, x);
262
- })
263
- .define_method(
264
- "_apply",
265
- *[](faiss::PCAMatrix &self, int64_t n, Rice::Object o) {
266
- const float *x = float_array(o);
267
- float* res = self.apply(n, x);
268
- return result(res, n * self.d_out);
269
- });
12
+ auto m = Rice::define_module("Faiss");
270
13
 
271
- Rice::define_class_under<faiss::ProductQuantizer>(rb_mFaiss, "ProductQuantizer")
272
- .define_constructor(Rice::Constructor<faiss::ProductQuantizer, size_t, size_t, size_t>())
273
- .define_method(
274
- "d",
275
- *[](faiss::ProductQuantizer &self) {
276
- return self.d;
277
- })
278
- .define_method(
279
- "m",
280
- *[](faiss::ProductQuantizer &self) {
281
- return self.M;
282
- })
283
- .define_method(
284
- "_train",
285
- *[](faiss::ProductQuantizer &self, int n, Rice::Object o) {
286
- const float *x = float_array(o);
287
- self.train(n, x);
288
- })
289
- .define_method(
290
- "_compute_codes",
291
- *[](faiss::ProductQuantizer &self, int n, Rice::Object o) {
292
- const float *x = float_array(o);
293
- uint8_t *codes = new uint8_t[n * self.M];
294
- self.compute_codes(x, codes, n);
295
- return result(codes, n * self.M);
296
- })
297
- .define_method(
298
- "_decode",
299
- *[](faiss::ProductQuantizer &self, int n, Rice::Object o) {
300
- const uint8_t *codes = uint8_array(o);
301
- float *x = new float[n * self.d];
302
- self.decode(codes, x, n);
303
- return result(x, n * self.d);
304
- })
305
- .define_method(
306
- "save",
307
- *[](faiss::ProductQuantizer &self, const char *fname) {
308
- faiss::write_ProductQuantizer(&self, fname);
309
- })
310
- .define_singleton_method(
311
- "load",
312
- *[](const char *fname) {
313
- return faiss::read_ProductQuantizer(fname);
314
- });
14
+ init_index(m);
15
+ init_index_binary(m);
16
+ init_kmeans(m);
17
+ init_pca_matrix(m);
18
+ init_product_quantizer(m);
315
19
  }
data/ext/faiss/extconf.rb CHANGED
@@ -4,14 +4,17 @@ abort "BLAS not found" unless have_library("blas")
4
4
  abort "LAPACK not found" unless have_library("lapack")
5
5
  abort "OpenMP not found" unless have_library("omp") || have_library("gomp")
6
6
 
7
- $CXXFLAGS << " -std=c++11 -march=native -DFINTEGER=int"
7
+ numo = $LOAD_PATH.find { |v| File.exist?("#{v}/numo/numo/narray.h") }
8
+ abort "Numo not found" unless numo && find_header("numo/narray.h", "#{numo}/numo")
9
+
10
+ $CXXFLAGS << " -std=c++17 $(optflags) -DFINTEGER=int " << with_config("optflags", "-march=native")
8
11
 
9
12
  ext = File.expand_path(".", __dir__)
10
13
  vendor = File.expand_path("../../vendor/faiss", __dir__)
11
14
 
12
15
  $srcs = Dir["{#{ext},#{vendor}/faiss,#{vendor}/faiss/{impl,invlists,utils}}/*.{cpp}"]
13
16
  $objs = $srcs.map { |v| v.sub(/cpp\z/, "o") }
14
- $INCFLAGS << " -I#{vendor}"
17
+ abort "Faiss not found" unless find_header("faiss/Index.h", vendor)
15
18
  $VPATH << vendor
16
19
 
17
20
  create_makefile("faiss/ext")
@@ -0,0 +1,189 @@
1
+ #include <faiss/Index.h>
2
+ #include <faiss/IndexFlat.h>
3
+ #include <faiss/IndexHNSW.h>
4
+ #include <faiss/IndexIVFFlat.h>
5
+ #include <faiss/IndexLSH.h>
6
+ #include <faiss/IndexScalarQuantizer.h>
7
+ #include <faiss/IndexPQ.h>
8
+ #include <faiss/IndexIVFPQ.h>
9
+ #include <faiss/IndexIVFPQR.h>
10
+ #include <faiss/index_io.h>
11
+ #include <faiss/AutoTune.h>
12
+
13
+ #include "utils.h"
14
+
15
+ namespace Rice::detail {
16
+ template<>
17
+ struct Type<faiss::MetricType>
18
+ {
19
+ static bool verify()
20
+ {
21
+ return true;
22
+ }
23
+ };
24
+
25
+ template<>
26
+ class From_Ruby<faiss::MetricType>
27
+ {
28
+ public:
29
+ From_Ruby() = default;
30
+
31
+ From_Ruby(Arg* arg) : arg_(arg)
32
+ {
33
+ }
34
+
35
+ faiss::MetricType convert(VALUE x)
36
+ {
37
+ if (x == Qnil && this->arg_ && this->arg_->hasDefaultValue()) {
38
+ return this->arg_->defaultValue<faiss::MetricType>();
39
+ }
40
+
41
+ auto s = Object(x).to_s().str();
42
+ if (s == "inner_product") {
43
+ return faiss::METRIC_INNER_PRODUCT;
44
+ } else if (s == "l2") {
45
+ return faiss::METRIC_L2;
46
+ } else {
47
+ throw Rice::Exception(rb_eArgError, "Invalid metric: %s", s.c_str());
48
+ }
49
+ }
50
+
51
+ private:
52
+ Arg* arg_;
53
+ };
54
+
55
+ template<>
56
+ struct Type<faiss::ScalarQuantizer::QuantizerType>
57
+ {
58
+ static bool verify()
59
+ {
60
+ return true;
61
+ }
62
+ };
63
+
64
+ template<>
65
+ class From_Ruby<faiss::ScalarQuantizer::QuantizerType>
66
+ {
67
+ public:
68
+ faiss::ScalarQuantizer::QuantizerType convert(VALUE x)
69
+ {
70
+ auto s = Object(x).to_s().str();
71
+ if (s == "qt_8bit") {
72
+ return faiss::ScalarQuantizer::QT_8bit;
73
+ } else if (s == "qt_4bit") {
74
+ return faiss::ScalarQuantizer::QT_4bit;
75
+ } else if (s == "qt_8bit_uniform") {
76
+ return faiss::ScalarQuantizer::QT_8bit_uniform;
77
+ } else if (s == "qt_4bit_uniform") {
78
+ return faiss::ScalarQuantizer::QT_4bit_uniform;
79
+ } else if (s == "qt_fp16") {
80
+ return faiss::ScalarQuantizer::QT_fp16;
81
+ } else if (s == "qt_8bit_direct") {
82
+ return faiss::ScalarQuantizer::QT_8bit_direct;
83
+ } else if (s == "qt_6bit") {
84
+ return faiss::ScalarQuantizer::QT_6bit;
85
+ } else {
86
+ throw Rice::Exception(rb_eArgError, "Invalid quantizer type: %s", s.c_str());
87
+ }
88
+ }
89
+ };
90
+ }
91
+
92
+ void init_index(Rice::Module& m) {
93
+ Rice::define_class_under<faiss::Index>(m, "Index")
94
+ .define_method(
95
+ "d",
96
+ [](faiss::Index &self) {
97
+ return self.d;
98
+ })
99
+ .define_method(
100
+ "trained?",
101
+ [](faiss::Index &self) {
102
+ return self.is_trained;
103
+ })
104
+ .define_method(
105
+ "ntotal",
106
+ [](faiss::Index &self) {
107
+ return self.ntotal;
108
+ })
109
+ .define_method(
110
+ "train",
111
+ [](faiss::Index &self, numo::SFloat objects) {
112
+ auto n = check_shape(objects, self.d);
113
+ self.train(n, objects.read_ptr());
114
+ })
115
+ .define_method(
116
+ "add",
117
+ [](faiss::Index &self, numo::SFloat objects) {
118
+ auto n = check_shape(objects, self.d);
119
+ self.add(n, objects.read_ptr());
120
+ })
121
+ .define_method(
122
+ "search",
123
+ [](faiss::Index &self, numo::SFloat objects, size_t k) {
124
+ auto n = check_shape(objects, self.d);
125
+
126
+ auto distances = numo::SFloat({n, k});
127
+ auto labels = numo::Int64({n, k});
128
+
129
+ self.search(n, objects.read_ptr(), k, distances.write_ptr(), labels.write_ptr());
130
+
131
+ Rice::Array ret;
132
+ ret.push(distances);
133
+ ret.push(labels);
134
+ return ret;
135
+ })
136
+ .define_method(
137
+ "nprobe=",
138
+ [](faiss::Index &self, double val) {
139
+ faiss::ParameterSpace().set_index_parameter(&self, "nprobe", val);
140
+ })
141
+ .define_method(
142
+ "save",
143
+ [](faiss::Index &self, const char *fname) {
144
+ faiss::write_index(&self, fname);
145
+ })
146
+ .define_singleton_function(
147
+ "load",
148
+ [](const char *fname) {
149
+ return faiss::read_index(fname);
150
+ });
151
+
152
+ Rice::define_class_under<faiss::IndexFlatL2, faiss::Index>(m, "IndexFlatL2")
153
+ .define_constructor(Rice::Constructor<faiss::IndexFlatL2, int64_t>());
154
+
155
+ Rice::define_class_under<faiss::IndexFlatIP, faiss::Index>(m, "IndexFlatIP")
156
+ .define_constructor(Rice::Constructor<faiss::IndexFlatIP, int64_t>());
157
+
158
+ Rice::define_class_under<faiss::IndexHNSWFlat, faiss::Index>(m, "IndexHNSWFlat")
159
+ .define_constructor(Rice::Constructor<faiss::IndexHNSWFlat, int, int, faiss::MetricType>(), Rice::Arg("d"), Rice::Arg("M"), Rice::Arg("metric") = faiss::METRIC_L2);
160
+
161
+ Rice::define_class_under<faiss::IndexIVFFlat, faiss::Index>(m, "IndexIVFFlat")
162
+ .define_constructor(Rice::Constructor<faiss::IndexIVFFlat, faiss::Index*, size_t, size_t, faiss::MetricType>(), Rice::Arg("quantizer"), Rice::Arg("d"), Rice::Arg("nlist"), Rice::Arg("metric") = faiss::METRIC_L2);
163
+
164
+ Rice::define_class_under<faiss::IndexLSH, faiss::Index>(m, "IndexLSH")
165
+ .define_constructor(Rice::Constructor<faiss::IndexLSH, int64_t, int>());
166
+
167
+ Rice::define_class_under<faiss::IndexScalarQuantizer, faiss::Index>(m, "IndexScalarQuantizer")
168
+ .define_constructor(Rice::Constructor<faiss::IndexScalarQuantizer, int, faiss::ScalarQuantizer::QuantizerType>());
169
+
170
+ Rice::define_class_under<faiss::IndexPQ, faiss::Index>(m, "IndexPQ")
171
+ .define_constructor(Rice::Constructor<faiss::IndexPQ, int, size_t, size_t>());
172
+
173
+ Rice::define_class_under<faiss::IndexIVFScalarQuantizer, faiss::Index>(m, "IndexIVFScalarQuantizer")
174
+ .define_constructor(Rice::Constructor<faiss::IndexIVFScalarQuantizer, faiss::Index*, size_t, size_t, faiss::ScalarQuantizer::QuantizerType>());
175
+
176
+ Rice::define_class_under<faiss::IndexIVFPQ, faiss::Index>(m, "IndexIVFPQ")
177
+ .define_constructor(Rice::Constructor<faiss::IndexIVFPQ, faiss::Index*, size_t, size_t, size_t, size_t, faiss::MetricType>(), Rice::Arg("quantizer"), Rice::Arg("d"), Rice::Arg("nlist"), Rice::Arg("M"), Rice::Arg("nbits_per_idx"), Rice::Arg("metric") = faiss::METRIC_L2);
178
+
179
+ Rice::define_class_under<faiss::IndexIVFPQR, faiss::Index>(m, "IndexIVFPQR")
180
+ .define_constructor(Rice::Constructor<faiss::IndexIVFPQR, faiss::Index*, size_t, size_t, size_t, size_t, size_t, size_t>());
181
+
182
+ Rice::define_class_under<faiss::ParameterSpace>(m, "ParameterSpace")
183
+ .define_constructor(Rice::Constructor<faiss::ParameterSpace>())
184
+ .define_method(
185
+ "set_index_parameter",
186
+ [](faiss::ParameterSpace& self, faiss::Index* index, const std::string& name, double val) {
187
+ self.set_index_parameter(index, name, val);
188
+ });
189
+ }