faiss 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (226) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +103 -3
  4. data/ext/faiss/ext.cpp +99 -32
  5. data/ext/faiss/extconf.rb +12 -2
  6. data/lib/faiss/ext.bundle +0 -0
  7. data/lib/faiss/index.rb +3 -3
  8. data/lib/faiss/index_binary.rb +3 -3
  9. data/lib/faiss/kmeans.rb +1 -1
  10. data/lib/faiss/pca_matrix.rb +2 -2
  11. data/lib/faiss/product_quantizer.rb +3 -3
  12. data/lib/faiss/version.rb +1 -1
  13. data/vendor/faiss/AutoTune.cpp +719 -0
  14. data/vendor/faiss/AutoTune.h +212 -0
  15. data/vendor/faiss/Clustering.cpp +261 -0
  16. data/vendor/faiss/Clustering.h +101 -0
  17. data/vendor/faiss/IVFlib.cpp +339 -0
  18. data/vendor/faiss/IVFlib.h +132 -0
  19. data/vendor/faiss/Index.cpp +171 -0
  20. data/vendor/faiss/Index.h +261 -0
  21. data/vendor/faiss/Index2Layer.cpp +437 -0
  22. data/vendor/faiss/Index2Layer.h +85 -0
  23. data/vendor/faiss/IndexBinary.cpp +77 -0
  24. data/vendor/faiss/IndexBinary.h +163 -0
  25. data/vendor/faiss/IndexBinaryFlat.cpp +83 -0
  26. data/vendor/faiss/IndexBinaryFlat.h +54 -0
  27. data/vendor/faiss/IndexBinaryFromFloat.cpp +78 -0
  28. data/vendor/faiss/IndexBinaryFromFloat.h +52 -0
  29. data/vendor/faiss/IndexBinaryHNSW.cpp +325 -0
  30. data/vendor/faiss/IndexBinaryHNSW.h +56 -0
  31. data/vendor/faiss/IndexBinaryIVF.cpp +671 -0
  32. data/vendor/faiss/IndexBinaryIVF.h +211 -0
  33. data/vendor/faiss/IndexFlat.cpp +508 -0
  34. data/vendor/faiss/IndexFlat.h +175 -0
  35. data/vendor/faiss/IndexHNSW.cpp +1090 -0
  36. data/vendor/faiss/IndexHNSW.h +170 -0
  37. data/vendor/faiss/IndexIVF.cpp +909 -0
  38. data/vendor/faiss/IndexIVF.h +353 -0
  39. data/vendor/faiss/IndexIVFFlat.cpp +502 -0
  40. data/vendor/faiss/IndexIVFFlat.h +118 -0
  41. data/vendor/faiss/IndexIVFPQ.cpp +1207 -0
  42. data/vendor/faiss/IndexIVFPQ.h +161 -0
  43. data/vendor/faiss/IndexIVFPQR.cpp +219 -0
  44. data/vendor/faiss/IndexIVFPQR.h +65 -0
  45. data/vendor/faiss/IndexIVFSpectralHash.cpp +331 -0
  46. data/vendor/faiss/IndexIVFSpectralHash.h +75 -0
  47. data/vendor/faiss/IndexLSH.cpp +225 -0
  48. data/vendor/faiss/IndexLSH.h +87 -0
  49. data/vendor/faiss/IndexLattice.cpp +143 -0
  50. data/vendor/faiss/IndexLattice.h +68 -0
  51. data/vendor/faiss/IndexPQ.cpp +1188 -0
  52. data/vendor/faiss/IndexPQ.h +199 -0
  53. data/vendor/faiss/IndexPreTransform.cpp +288 -0
  54. data/vendor/faiss/IndexPreTransform.h +91 -0
  55. data/vendor/faiss/IndexReplicas.cpp +123 -0
  56. data/vendor/faiss/IndexReplicas.h +76 -0
  57. data/vendor/faiss/IndexScalarQuantizer.cpp +317 -0
  58. data/vendor/faiss/IndexScalarQuantizer.h +127 -0
  59. data/vendor/faiss/IndexShards.cpp +317 -0
  60. data/vendor/faiss/IndexShards.h +100 -0
  61. data/vendor/faiss/InvertedLists.cpp +623 -0
  62. data/vendor/faiss/InvertedLists.h +334 -0
  63. data/vendor/faiss/LICENSE +21 -0
  64. data/vendor/faiss/MatrixStats.cpp +252 -0
  65. data/vendor/faiss/MatrixStats.h +62 -0
  66. data/vendor/faiss/MetaIndexes.cpp +351 -0
  67. data/vendor/faiss/MetaIndexes.h +126 -0
  68. data/vendor/faiss/OnDiskInvertedLists.cpp +674 -0
  69. data/vendor/faiss/OnDiskInvertedLists.h +127 -0
  70. data/vendor/faiss/VectorTransform.cpp +1157 -0
  71. data/vendor/faiss/VectorTransform.h +322 -0
  72. data/vendor/faiss/c_api/AutoTune_c.cpp +83 -0
  73. data/vendor/faiss/c_api/AutoTune_c.h +64 -0
  74. data/vendor/faiss/c_api/Clustering_c.cpp +139 -0
  75. data/vendor/faiss/c_api/Clustering_c.h +117 -0
  76. data/vendor/faiss/c_api/IndexFlat_c.cpp +140 -0
  77. data/vendor/faiss/c_api/IndexFlat_c.h +115 -0
  78. data/vendor/faiss/c_api/IndexIVFFlat_c.cpp +64 -0
  79. data/vendor/faiss/c_api/IndexIVFFlat_c.h +58 -0
  80. data/vendor/faiss/c_api/IndexIVF_c.cpp +92 -0
  81. data/vendor/faiss/c_api/IndexIVF_c.h +135 -0
  82. data/vendor/faiss/c_api/IndexLSH_c.cpp +37 -0
  83. data/vendor/faiss/c_api/IndexLSH_c.h +40 -0
  84. data/vendor/faiss/c_api/IndexShards_c.cpp +44 -0
  85. data/vendor/faiss/c_api/IndexShards_c.h +42 -0
  86. data/vendor/faiss/c_api/Index_c.cpp +105 -0
  87. data/vendor/faiss/c_api/Index_c.h +183 -0
  88. data/vendor/faiss/c_api/MetaIndexes_c.cpp +49 -0
  89. data/vendor/faiss/c_api/MetaIndexes_c.h +49 -0
  90. data/vendor/faiss/c_api/clone_index_c.cpp +23 -0
  91. data/vendor/faiss/c_api/clone_index_c.h +32 -0
  92. data/vendor/faiss/c_api/error_c.h +42 -0
  93. data/vendor/faiss/c_api/error_impl.cpp +27 -0
  94. data/vendor/faiss/c_api/error_impl.h +16 -0
  95. data/vendor/faiss/c_api/faiss_c.h +58 -0
  96. data/vendor/faiss/c_api/gpu/GpuAutoTune_c.cpp +96 -0
  97. data/vendor/faiss/c_api/gpu/GpuAutoTune_c.h +56 -0
  98. data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.cpp +52 -0
  99. data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.h +68 -0
  100. data/vendor/faiss/c_api/gpu/GpuIndex_c.cpp +17 -0
  101. data/vendor/faiss/c_api/gpu/GpuIndex_c.h +30 -0
  102. data/vendor/faiss/c_api/gpu/GpuIndicesOptions_c.h +38 -0
  103. data/vendor/faiss/c_api/gpu/GpuResources_c.cpp +86 -0
  104. data/vendor/faiss/c_api/gpu/GpuResources_c.h +66 -0
  105. data/vendor/faiss/c_api/gpu/StandardGpuResources_c.cpp +54 -0
  106. data/vendor/faiss/c_api/gpu/StandardGpuResources_c.h +53 -0
  107. data/vendor/faiss/c_api/gpu/macros_impl.h +42 -0
  108. data/vendor/faiss/c_api/impl/AuxIndexStructures_c.cpp +220 -0
  109. data/vendor/faiss/c_api/impl/AuxIndexStructures_c.h +149 -0
  110. data/vendor/faiss/c_api/index_factory_c.cpp +26 -0
  111. data/vendor/faiss/c_api/index_factory_c.h +30 -0
  112. data/vendor/faiss/c_api/index_io_c.cpp +42 -0
  113. data/vendor/faiss/c_api/index_io_c.h +50 -0
  114. data/vendor/faiss/c_api/macros_impl.h +110 -0
  115. data/vendor/faiss/clone_index.cpp +147 -0
  116. data/vendor/faiss/clone_index.h +38 -0
  117. data/vendor/faiss/demos/demo_imi_flat.cpp +151 -0
  118. data/vendor/faiss/demos/demo_imi_pq.cpp +199 -0
  119. data/vendor/faiss/demos/demo_ivfpq_indexing.cpp +146 -0
  120. data/vendor/faiss/demos/demo_sift1M.cpp +252 -0
  121. data/vendor/faiss/gpu/GpuAutoTune.cpp +95 -0
  122. data/vendor/faiss/gpu/GpuAutoTune.h +27 -0
  123. data/vendor/faiss/gpu/GpuCloner.cpp +403 -0
  124. data/vendor/faiss/gpu/GpuCloner.h +82 -0
  125. data/vendor/faiss/gpu/GpuClonerOptions.cpp +28 -0
  126. data/vendor/faiss/gpu/GpuClonerOptions.h +53 -0
  127. data/vendor/faiss/gpu/GpuDistance.h +52 -0
  128. data/vendor/faiss/gpu/GpuFaissAssert.h +29 -0
  129. data/vendor/faiss/gpu/GpuIndex.h +148 -0
  130. data/vendor/faiss/gpu/GpuIndexBinaryFlat.h +89 -0
  131. data/vendor/faiss/gpu/GpuIndexFlat.h +190 -0
  132. data/vendor/faiss/gpu/GpuIndexIVF.h +89 -0
  133. data/vendor/faiss/gpu/GpuIndexIVFFlat.h +85 -0
  134. data/vendor/faiss/gpu/GpuIndexIVFPQ.h +143 -0
  135. data/vendor/faiss/gpu/GpuIndexIVFScalarQuantizer.h +100 -0
  136. data/vendor/faiss/gpu/GpuIndicesOptions.h +30 -0
  137. data/vendor/faiss/gpu/GpuResources.cpp +52 -0
  138. data/vendor/faiss/gpu/GpuResources.h +73 -0
  139. data/vendor/faiss/gpu/StandardGpuResources.cpp +295 -0
  140. data/vendor/faiss/gpu/StandardGpuResources.h +114 -0
  141. data/vendor/faiss/gpu/impl/RemapIndices.cpp +43 -0
  142. data/vendor/faiss/gpu/impl/RemapIndices.h +24 -0
  143. data/vendor/faiss/gpu/perf/IndexWrapper-inl.h +71 -0
  144. data/vendor/faiss/gpu/perf/IndexWrapper.h +39 -0
  145. data/vendor/faiss/gpu/perf/PerfClustering.cpp +115 -0
  146. data/vendor/faiss/gpu/perf/PerfIVFPQAdd.cpp +139 -0
  147. data/vendor/faiss/gpu/perf/WriteIndex.cpp +102 -0
  148. data/vendor/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +130 -0
  149. data/vendor/faiss/gpu/test/TestGpuIndexFlat.cpp +371 -0
  150. data/vendor/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +550 -0
  151. data/vendor/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +450 -0
  152. data/vendor/faiss/gpu/test/TestGpuMemoryException.cpp +84 -0
  153. data/vendor/faiss/gpu/test/TestUtils.cpp +315 -0
  154. data/vendor/faiss/gpu/test/TestUtils.h +93 -0
  155. data/vendor/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +159 -0
  156. data/vendor/faiss/gpu/utils/DeviceMemory.cpp +77 -0
  157. data/vendor/faiss/gpu/utils/DeviceMemory.h +71 -0
  158. data/vendor/faiss/gpu/utils/DeviceUtils.h +185 -0
  159. data/vendor/faiss/gpu/utils/MemorySpace.cpp +89 -0
  160. data/vendor/faiss/gpu/utils/MemorySpace.h +44 -0
  161. data/vendor/faiss/gpu/utils/StackDeviceMemory.cpp +239 -0
  162. data/vendor/faiss/gpu/utils/StackDeviceMemory.h +129 -0
  163. data/vendor/faiss/gpu/utils/StaticUtils.h +83 -0
  164. data/vendor/faiss/gpu/utils/Timer.cpp +60 -0
  165. data/vendor/faiss/gpu/utils/Timer.h +52 -0
  166. data/vendor/faiss/impl/AuxIndexStructures.cpp +305 -0
  167. data/vendor/faiss/impl/AuxIndexStructures.h +246 -0
  168. data/vendor/faiss/impl/FaissAssert.h +95 -0
  169. data/vendor/faiss/impl/FaissException.cpp +66 -0
  170. data/vendor/faiss/impl/FaissException.h +71 -0
  171. data/vendor/faiss/impl/HNSW.cpp +818 -0
  172. data/vendor/faiss/impl/HNSW.h +275 -0
  173. data/vendor/faiss/impl/PolysemousTraining.cpp +953 -0
  174. data/vendor/faiss/impl/PolysemousTraining.h +158 -0
  175. data/vendor/faiss/impl/ProductQuantizer.cpp +876 -0
  176. data/vendor/faiss/impl/ProductQuantizer.h +242 -0
  177. data/vendor/faiss/impl/ScalarQuantizer.cpp +1628 -0
  178. data/vendor/faiss/impl/ScalarQuantizer.h +120 -0
  179. data/vendor/faiss/impl/ThreadedIndex-inl.h +192 -0
  180. data/vendor/faiss/impl/ThreadedIndex.h +80 -0
  181. data/vendor/faiss/impl/index_read.cpp +793 -0
  182. data/vendor/faiss/impl/index_write.cpp +558 -0
  183. data/vendor/faiss/impl/io.cpp +142 -0
  184. data/vendor/faiss/impl/io.h +98 -0
  185. data/vendor/faiss/impl/lattice_Zn.cpp +712 -0
  186. data/vendor/faiss/impl/lattice_Zn.h +199 -0
  187. data/vendor/faiss/index_factory.cpp +392 -0
  188. data/vendor/faiss/index_factory.h +25 -0
  189. data/vendor/faiss/index_io.h +75 -0
  190. data/vendor/faiss/misc/test_blas.cpp +84 -0
  191. data/vendor/faiss/tests/test_binary_flat.cpp +64 -0
  192. data/vendor/faiss/tests/test_dealloc_invlists.cpp +183 -0
  193. data/vendor/faiss/tests/test_ivfpq_codec.cpp +67 -0
  194. data/vendor/faiss/tests/test_ivfpq_indexing.cpp +98 -0
  195. data/vendor/faiss/tests/test_lowlevel_ivf.cpp +566 -0
  196. data/vendor/faiss/tests/test_merge.cpp +258 -0
  197. data/vendor/faiss/tests/test_omp_threads.cpp +14 -0
  198. data/vendor/faiss/tests/test_ondisk_ivf.cpp +220 -0
  199. data/vendor/faiss/tests/test_pairs_decoding.cpp +189 -0
  200. data/vendor/faiss/tests/test_params_override.cpp +231 -0
  201. data/vendor/faiss/tests/test_pq_encoding.cpp +98 -0
  202. data/vendor/faiss/tests/test_sliding_ivf.cpp +240 -0
  203. data/vendor/faiss/tests/test_threaded_index.cpp +253 -0
  204. data/vendor/faiss/tests/test_transfer_invlists.cpp +159 -0
  205. data/vendor/faiss/tutorial/cpp/1-Flat.cpp +98 -0
  206. data/vendor/faiss/tutorial/cpp/2-IVFFlat.cpp +81 -0
  207. data/vendor/faiss/tutorial/cpp/3-IVFPQ.cpp +93 -0
  208. data/vendor/faiss/tutorial/cpp/4-GPU.cpp +119 -0
  209. data/vendor/faiss/tutorial/cpp/5-Multiple-GPUs.cpp +99 -0
  210. data/vendor/faiss/utils/Heap.cpp +122 -0
  211. data/vendor/faiss/utils/Heap.h +495 -0
  212. data/vendor/faiss/utils/WorkerThread.cpp +126 -0
  213. data/vendor/faiss/utils/WorkerThread.h +61 -0
  214. data/vendor/faiss/utils/distances.cpp +765 -0
  215. data/vendor/faiss/utils/distances.h +243 -0
  216. data/vendor/faiss/utils/distances_simd.cpp +809 -0
  217. data/vendor/faiss/utils/extra_distances.cpp +336 -0
  218. data/vendor/faiss/utils/extra_distances.h +54 -0
  219. data/vendor/faiss/utils/hamming-inl.h +472 -0
  220. data/vendor/faiss/utils/hamming.cpp +792 -0
  221. data/vendor/faiss/utils/hamming.h +220 -0
  222. data/vendor/faiss/utils/random.cpp +192 -0
  223. data/vendor/faiss/utils/random.h +60 -0
  224. data/vendor/faiss/utils/utils.cpp +783 -0
  225. data/vendor/faiss/utils/utils.h +181 -0
  226. metadata +216 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47b973803ea179379ab292d5d7b8350c12a383387e90b96f38eae4e90e20dad3
4
- data.tar.gz: 5697b1ec26dbbb0794e6c11563b0cf76d564391882e7c0c0148f3893e1bf6b59
3
+ metadata.gz: a0369e5dda330b1490e48a88863baa01df9cadfa570078892cec439f82efaad1
4
+ data.tar.gz: bb7d89fa17f782e8163b114b520b8c2c082cf37661b4b6fc4593460dc5958484
5
5
  SHA512:
6
- metadata.gz: dccf5a8ddfd4030e70308c3e71b16bb6742839b8b1a263d3a010a381729af869c1755164e25a3941a3f475376e783ec42b43409fede77010e97949092a424e18
7
- data.tar.gz: 57c933bc9d3ffbec37be0edbf641bd004e8dbfa13c04d52ca970e8ff03f719f65f27016892b06cd66755f36afc8d3ff505e6062656f2c48fa20d58cf64c2b6fd
6
+ metadata.gz: 0a9f1515d142d11c688f1a9cdbcf9af0c36fa3fc98b240f236554b1067cf2daad1cefa377d18d236674b8fc1b94d64a3acc070c2528c47b68f4d231f29b7648d
7
+ data.tar.gz: ae02808dbda4831c7165c987b77c72f9d436bba94e3e28d372f69ceee18fb4971c6cc99a2bf7ce9bd9a9a6e4befcd372515a728bf379294ecc870f2c58f85eb2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.1.1 (2020-03-09)
2
+
3
+ - Vendored library
4
+ - Added `save` and `load` methods
5
+
1
6
  ## 0.1.0 (2020-03-08)
2
7
 
3
8
  - First release
data/README.md CHANGED
@@ -2,12 +2,20 @@
2
2
 
3
3
  [Faiss](https://github.com/facebookresearch/faiss) - efficient similarity search and clustering - for Ruby
4
4
 
5
+ Learn more about [Faiss](https://engineering.fb.com/data-infrastructure/faiss-a-library-for-efficient-similarity-search/)
6
+
7
+ [![Build Status](https://travis-ci.org/ankane/faiss.svg?branch=master)](https://travis-ci.org/ankane/faiss)
8
+
5
9
  ## Installation
6
10
 
7
- First, install the [Faiss C++ library](https://github.com/facebookresearch/faiss/blob/master/INSTALL.md). For Homebrew, use:
11
+ First, install BLAS, LAPACK, and OpenMP:
8
12
 
9
13
  ```sh
10
- brew install faiss
14
+ # Mac
15
+ brew install openblas lapack libomp
16
+
17
+ # Ubuntu
18
+ sudo apt install libblas-dev liblapack-dev
11
19
  ```
12
20
 
13
21
  Add this line to your application’s Gemfile:
@@ -16,6 +24,8 @@ Add this line to your application’s Gemfile:
16
24
  gem 'faiss'
17
25
  ```
18
26
 
27
+ Faiss is not available for Windows yet
28
+
19
29
  ## Getting Started
20
30
 
21
31
  Prep your data
@@ -41,6 +51,84 @@ Search
41
51
  distances, ids = index.search(objects, 3)
42
52
  ```
43
53
 
54
+ Save an index
55
+
56
+ ```ruby
57
+ index.save("index.bin")
58
+ ```
59
+
60
+ Load an index
61
+
62
+ ```ruby
63
+ index = Faiss::Index.load("index.bin")
64
+ ```
65
+
66
+ > Use `Faiss::IndexBinary` to load binary indexes
67
+
68
+ ## Basic Indexes
69
+
70
+ Exact search for L2
71
+
72
+ ```rb
73
+ Faiss::IndexFlatL2.new(d)
74
+ ```
75
+
76
+ Exact search for inner product
77
+
78
+ ```rb
79
+ Faiss::IndexFlatIP.new(d)
80
+ ```
81
+
82
+ Hierarchical navigable small world graph exploration
83
+
84
+ ```rb
85
+ Faiss::IndexHNSWFlat.new(d, m)
86
+ ```
87
+
88
+ Inverted file with exact post-verification
89
+
90
+ ```rb
91
+ Faiss::IndexIVFFlat.new(quantizer, d, nlists)
92
+ ```
93
+
94
+ Locality-sensitive hashing
95
+
96
+ ```rb
97
+ Faiss::IndexLSH.new(d, nbits)
98
+ ```
99
+
100
+ Product quantizer (PQ) in flat mode
101
+
102
+ ```rb
103
+ Faiss::IndexPQ.new(d, m, nbits)
104
+ ```
105
+
106
+ IVFADC (coarse quantizer+PQ on residuals)
107
+
108
+ ```rb
109
+ Faiss::IndexIVFPQ.new(quantizer, d, nlists, m, nbits)
110
+ ```
111
+
112
+ IVFADC+R (same as IVFADC with re-ranking based on codes)
113
+
114
+ ```rb
115
+ Faiss::IndexIVFPQR.new(quantizer, d, nlists, m, nbits, m_refine, nbits_refine)
116
+ ```
117
+
118
+ ## Binary Indexes
119
+
120
+ Index binary vectors
121
+
122
+ ```rb
123
+ Faiss::IndexBinaryFlat.new(d)
124
+ ```
125
+
126
+ Speed up search with an inverse vector file
127
+
128
+ ```rb
129
+ Faiss::IndexBinaryIVF.new(quantizer, d, nlists)
130
+ ```
131
+
44
132
  ## K-means Clustering
45
133
 
46
134
  Train
@@ -92,6 +180,18 @@ Decode
92
180
  pq.decode(codes)
93
181
  ```
94
182
 
183
+ Save a quantizer
184
+
185
+ ```ruby
186
+ pq.save("pq.bin")
187
+ ```
188
+
189
+ Load a quantizer
190
+
191
+ ```ruby
192
+ pq = Faiss::ProductQuantizer.load("pq.bin")
193
+ ```
194
+
95
195
  ## Data
96
196
 
97
197
  Data can be an array of arrays
@@ -122,7 +222,7 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
122
222
  To get started with development:
123
223
 
124
224
  ```sh
125
- git clone https://github.com/ankane/faiss.git
225
+ git clone --recursive https://github.com/ankane/faiss.git
126
226
  cd faiss
127
227
  bundle install
128
228
  bundle exec rake compile
data/ext/faiss/ext.cpp CHANGED
@@ -10,6 +10,7 @@
10
10
  #include <faiss/IndexBinaryFlat.h>
11
11
  #include <faiss/IndexBinaryIVF.h>
12
12
  #include <faiss/index_factory.h>
13
+ #include <faiss/index_io.h>
13
14
 
14
15
  #include <faiss/Clustering.h>
15
16
  #include <faiss/VectorTransform.h>
@@ -19,6 +20,42 @@
19
20
  #include <rice/Constructor.hpp>
20
21
  #include <rice/Module.hpp>
21
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
+ }
58
+
22
59
  extern "C"
23
60
  void Init_ext()
24
61
  {
@@ -47,32 +84,42 @@ void Init_ext()
47
84
  })
48
85
  .define_method(
49
86
  "_train",
50
- *[](faiss::Index &self, int64_t n, Rice::String s) {
51
- const float *x = (float*) s.c_str();
87
+ *[](faiss::Index &self, int64_t n, Rice::Object o) {
88
+ const float *x = float_array(o);
52
89
  self.train(n, x);
53
90
  })
54
91
  .define_method(
55
92
  "_add",
56
- *[](faiss::Index &self, int64_t n, Rice::String s) {
57
- const float *x = (float*) s.c_str();
93
+ *[](faiss::Index &self, int64_t n, Rice::Object o) {
94
+ const float *x = float_array(o);
58
95
  self.add(n, x);
59
96
  })
60
97
  .define_method(
61
98
  "_search",
62
- *[](faiss::Index &self, int64_t n, Rice::String s, int64_t k) {
63
- const float *x = (float*) s.c_str();
99
+ *[](faiss::Index &self, int64_t n, Rice::Object o, int64_t k) {
100
+ const float *x = float_array(o);
64
101
  float *distances = new float[k * n];
65
102
  int64_t *labels = new int64_t[k * n];
66
103
 
67
104
  self.search(n, x, k, distances, labels);
68
105
 
69
- auto dstr = std::string((char*) distances, k * n * sizeof(float));
70
- auto lstr = std::string((char*) labels, k * n * sizeof(int64_t));
106
+ auto dstr = result(distances, k * n);
107
+ auto lstr = result(labels, k * n);
71
108
 
72
109
  Rice::Array ret;
73
110
  ret.push(dstr);
74
111
  ret.push(lstr);
75
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);
76
123
  });
77
124
 
78
125
  Rice::define_class_under<faiss::IndexBinary>(rb_mFaiss, "IndexBinary")
@@ -93,32 +140,42 @@ void Init_ext()
93
140
  })
94
141
  .define_method(
95
142
  "_train",
96
- *[](faiss::IndexBinary &self, int64_t n, Rice::String s) {
97
- const uint8_t *x = (uint8_t*) s.c_str();
143
+ *[](faiss::IndexBinary &self, int64_t n, Rice::Object o) {
144
+ const uint8_t *x = uint8_array(o);
98
145
  self.train(n, x);
99
146
  })
100
147
  .define_method(
101
148
  "_add",
102
- *[](faiss::IndexBinary &self, int64_t n, Rice::String s) {
103
- const uint8_t *x = (uint8_t*) s.c_str();
149
+ *[](faiss::IndexBinary &self, int64_t n, Rice::Object o) {
150
+ const uint8_t *x = uint8_array(o);
104
151
  self.add(n, x);
105
152
  })
106
153
  .define_method(
107
154
  "_search",
108
- *[](faiss::IndexBinary &self, int64_t n, Rice::String s, int64_t k) {
109
- const uint8_t *x = (uint8_t*) s.c_str();
155
+ *[](faiss::IndexBinary &self, int64_t n, Rice::Object o, int64_t k) {
156
+ const uint8_t *x = uint8_array(o);
110
157
  int32_t *distances = new int32_t[k * n];
111
158
  int64_t *labels = new int64_t[k * n];
112
159
 
113
160
  self.search(n, x, k, distances, labels);
114
161
 
115
- auto dstr = std::string((char*) distances, k * n * sizeof(int32_t));
116
- auto lstr = std::string((char*) labels, k * n * sizeof(int64_t));
162
+ auto dstr = result(distances, k * n);
163
+ auto lstr = result(labels, k * n);
117
164
 
118
165
  Rice::Array ret;
119
166
  ret.push(dstr);
120
167
  ret.push(lstr);
121
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);
122
179
  });
123
180
 
124
181
  Rice::define_class_under<faiss::IndexFlatL2, faiss::Index>(rb_mFaiss, "IndexFlatL2")
@@ -176,12 +233,12 @@ void Init_ext()
176
233
  for (size_t i = 0; i < self.centroids.size(); i++) {
177
234
  centroids[i] = self.centroids[i];
178
235
  }
179
- return std::string((char*) centroids, self.k * self.d * sizeof(float));
236
+ return result(centroids, self.k * self.d);
180
237
  })
181
238
  .define_method(
182
239
  "_train",
183
- *[](faiss::Clustering &self, int64_t n, Rice::String s, faiss::Index & index) {
184
- const float *x = (float*) s.c_str();
240
+ *[](faiss::Clustering &self, int64_t n, Rice::Object o, faiss::Index & index) {
241
+ const float *x = float_array(o);
185
242
  self.train(n, x, index);
186
243
  });
187
244
 
@@ -199,16 +256,16 @@ void Init_ext()
199
256
  })
200
257
  .define_method(
201
258
  "_train",
202
- *[](faiss::PCAMatrix &self, int64_t n, Rice::String s) {
203
- const float *x = (float*) s.c_str();
259
+ *[](faiss::PCAMatrix &self, int64_t n, Rice::Object o) {
260
+ const float *x = float_array(o);
204
261
  self.train(n, x);
205
262
  })
206
263
  .define_method(
207
264
  "_apply",
208
- *[](faiss::PCAMatrix &self, int64_t n, Rice::String s) {
209
- const float *x = (float*) s.c_str();
265
+ *[](faiss::PCAMatrix &self, int64_t n, Rice::Object o) {
266
+ const float *x = float_array(o);
210
267
  float* res = self.apply(n, x);
211
- return std::string((char*) res, n * self.d_out * sizeof(float));
268
+ return result(res, n * self.d_out);
212
269
  });
213
270
 
214
271
  Rice::define_class_under<faiss::ProductQuantizer>(rb_mFaiss, "ProductQuantizer")
@@ -225,24 +282,34 @@ void Init_ext()
225
282
  })
226
283
  .define_method(
227
284
  "_train",
228
- *[](faiss::ProductQuantizer &self, int n, Rice::String s) {
229
- const float *x = (float*) s.c_str();
285
+ *[](faiss::ProductQuantizer &self, int n, Rice::Object o) {
286
+ const float *x = float_array(o);
230
287
  self.train(n, x);
231
288
  })
232
289
  .define_method(
233
290
  "_compute_codes",
234
- *[](faiss::ProductQuantizer &self, int n, Rice::String s) {
235
- const float *x = (float*) s.c_str();
291
+ *[](faiss::ProductQuantizer &self, int n, Rice::Object o) {
292
+ const float *x = float_array(o);
236
293
  uint8_t *codes = new uint8_t[n * self.M];
237
294
  self.compute_codes(x, codes, n);
238
- return std::string((char*) codes, n * self.M * sizeof(uint8_t));
295
+ return result(codes, n * self.M);
239
296
  })
240
297
  .define_method(
241
298
  "_decode",
242
- *[](faiss::ProductQuantizer &self, int n, Rice::String s) {
243
- const uint8_t *codes = (uint8_t*) s.c_str();
299
+ *[](faiss::ProductQuantizer &self, int n, Rice::Object o) {
300
+ const uint8_t *codes = uint8_array(o);
244
301
  float *x = new float[n * self.d];
245
302
  self.decode(codes, x, n);
246
- return std::string((char*) x, n * self.d * sizeof(float));
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);
247
314
  });
248
315
  }
data/ext/faiss/extconf.rb CHANGED
@@ -1,7 +1,17 @@
1
1
  require "mkmf-rice"
2
2
 
3
- abort "Missing faiss" unless have_library("faiss")
3
+ abort "BLAS not found" unless have_library("blas")
4
+ abort "LAPACK not found" unless have_library("lapack")
5
+ abort "OpenMP not found" unless have_library("omp") || have_library("gomp")
4
6
 
5
- $CXXFLAGS << " -std=c++11"
7
+ $CXXFLAGS << " -std=c++11 -march=native -DFINTEGER=int"
8
+
9
+ ext = File.expand_path(".", __dir__)
10
+ vendor = File.expand_path("../../vendor", __dir__)
11
+
12
+ $srcs = Dir["{#{ext},#{vendor}/faiss,#{vendor}/faiss/impl,#{vendor}/faiss/utils}/*.{cpp}"]
13
+ $objs = $srcs.map { |v| v.sub(/cpp\z/, "o") }
14
+ $INCFLAGS << " -I#{vendor}"
15
+ $VPATH << vendor
6
16
 
7
17
  create_makefile("faiss/ext")
Binary file
data/lib/faiss/index.rb CHANGED
@@ -2,18 +2,18 @@ module Faiss
2
2
  class Index
3
3
  def train(objects)
4
4
  objects = Numo::SFloat.cast(objects) unless objects.is_a?(Numo::SFloat)
5
- _train(objects.shape[0], objects.to_binary)
5
+ _train(objects.shape[0], objects)
6
6
  end
7
7
 
8
8
  def add(objects)
9
9
  objects = Numo::SFloat.cast(objects) unless objects.is_a?(Numo::SFloat)
10
- _add(objects.shape[0], objects.to_binary)
10
+ _add(objects.shape[0], objects)
11
11
  end
12
12
 
13
13
  def search(objects, k)
14
14
  objects = Numo::SFloat.cast(objects) unless objects.is_a?(Numo::SFloat)
15
15
  n = objects.shape[0]
16
- distances, labels = _search(n, objects.to_binary, k)
16
+ distances, labels = _search(n, objects, k)
17
17
  [Numo::SFloat.from_binary(distances).reshape(n, k), Numo::Int64.from_binary(labels).reshape(n, k)]
18
18
  end
19
19
  end
@@ -2,18 +2,18 @@ module Faiss
2
2
  class IndexBinary
3
3
  def train(objects)
4
4
  objects = Numo::UInt8.cast(objects) unless objects.is_a?(Numo::UInt8)
5
- _train(objects.shape[0], objects.to_binary)
5
+ _train(objects.shape[0], objects)
6
6
  end
7
7
 
8
8
  def add(objects)
9
9
  objects = Numo::UInt8.cast(objects) unless objects.is_a?(Numo::UInt8)
10
- _add(objects.shape[0], objects.to_binary)
10
+ _add(objects.shape[0], objects)
11
11
  end
12
12
 
13
13
  def search(objects, k)
14
14
  objects = Numo::UInt8.cast(objects) unless objects.is_a?(Numo::UInt8)
15
15
  n = objects.shape[0]
16
- distances, labels = _search(n, objects.to_binary, k)
16
+ distances, labels = _search(n, objects, k)
17
17
  [Numo::UInt32.from_binary(distances).reshape(n, k), Numo::Int64.from_binary(labels).reshape(n, k)]
18
18
  end
19
19
  end