faiss 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/ext/faiss/extconf.rb +1 -1
  4. data/lib/faiss/version.rb +1 -1
  5. data/vendor/faiss/benchs/bench_6bit_codec.cpp +80 -0
  6. data/vendor/faiss/c_api/AutoTune_c.h +2 -0
  7. data/vendor/faiss/c_api/IndexShards_c.cpp +0 -6
  8. data/vendor/faiss/c_api/IndexShards_c.h +1 -4
  9. data/vendor/faiss/c_api/gpu/GpuAutoTune_c.cpp +4 -2
  10. data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.cpp +1 -1
  11. data/vendor/faiss/c_api/gpu/GpuIndex_c.cpp +1 -1
  12. data/vendor/faiss/c_api/gpu/GpuResources_c.cpp +1 -1
  13. data/vendor/faiss/c_api/gpu/StandardGpuResources_c.cpp +1 -1
  14. data/vendor/faiss/demos/demo_imi_flat.cpp +5 -2
  15. data/vendor/faiss/demos/demo_imi_pq.cpp +6 -2
  16. data/vendor/faiss/demos/demo_ivfpq_indexing.cpp +7 -2
  17. data/vendor/faiss/{AutoTune.cpp → faiss/AutoTune.cpp} +9 -9
  18. data/vendor/faiss/{AutoTune.h → faiss/AutoTune.h} +0 -0
  19. data/vendor/faiss/{Clustering.cpp → faiss/Clustering.cpp} +13 -12
  20. data/vendor/faiss/{Clustering.h → faiss/Clustering.h} +0 -0
  21. data/vendor/faiss/{DirectMap.cpp → faiss/DirectMap.cpp} +0 -0
  22. data/vendor/faiss/{DirectMap.h → faiss/DirectMap.h} +0 -0
  23. data/vendor/faiss/{IVFlib.cpp → faiss/IVFlib.cpp} +86 -11
  24. data/vendor/faiss/{IVFlib.h → faiss/IVFlib.h} +26 -8
  25. data/vendor/faiss/{Index.cpp → faiss/Index.cpp} +0 -0
  26. data/vendor/faiss/{Index.h → faiss/Index.h} +1 -1
  27. data/vendor/faiss/{Index2Layer.cpp → faiss/Index2Layer.cpp} +12 -11
  28. data/vendor/faiss/{Index2Layer.h → faiss/Index2Layer.h} +0 -0
  29. data/vendor/faiss/{IndexBinary.cpp → faiss/IndexBinary.cpp} +2 -1
  30. data/vendor/faiss/{IndexBinary.h → faiss/IndexBinary.h} +0 -0
  31. data/vendor/faiss/{IndexBinaryFlat.cpp → faiss/IndexBinaryFlat.cpp} +0 -0
  32. data/vendor/faiss/{IndexBinaryFlat.h → faiss/IndexBinaryFlat.h} +0 -0
  33. data/vendor/faiss/{IndexBinaryFromFloat.cpp → faiss/IndexBinaryFromFloat.cpp} +1 -0
  34. data/vendor/faiss/{IndexBinaryFromFloat.h → faiss/IndexBinaryFromFloat.h} +0 -0
  35. data/vendor/faiss/{IndexBinaryHNSW.cpp → faiss/IndexBinaryHNSW.cpp} +1 -2
  36. data/vendor/faiss/{IndexBinaryHNSW.h → faiss/IndexBinaryHNSW.h} +0 -0
  37. data/vendor/faiss/{IndexBinaryHash.cpp → faiss/IndexBinaryHash.cpp} +16 -7
  38. data/vendor/faiss/{IndexBinaryHash.h → faiss/IndexBinaryHash.h} +2 -1
  39. data/vendor/faiss/{IndexBinaryIVF.cpp → faiss/IndexBinaryIVF.cpp} +10 -16
  40. data/vendor/faiss/{IndexBinaryIVF.h → faiss/IndexBinaryIVF.h} +1 -1
  41. data/vendor/faiss/{IndexFlat.cpp → faiss/IndexFlat.cpp} +0 -0
  42. data/vendor/faiss/{IndexFlat.h → faiss/IndexFlat.h} +0 -0
  43. data/vendor/faiss/{IndexHNSW.cpp → faiss/IndexHNSW.cpp} +63 -32
  44. data/vendor/faiss/{IndexHNSW.h → faiss/IndexHNSW.h} +0 -0
  45. data/vendor/faiss/{IndexIVF.cpp → faiss/IndexIVF.cpp} +129 -46
  46. data/vendor/faiss/{IndexIVF.h → faiss/IndexIVF.h} +7 -3
  47. data/vendor/faiss/{IndexIVFFlat.cpp → faiss/IndexIVFFlat.cpp} +6 -5
  48. data/vendor/faiss/{IndexIVFFlat.h → faiss/IndexIVFFlat.h} +0 -0
  49. data/vendor/faiss/{IndexIVFPQ.cpp → faiss/IndexIVFPQ.cpp} +9 -8
  50. data/vendor/faiss/{IndexIVFPQ.h → faiss/IndexIVFPQ.h} +4 -2
  51. data/vendor/faiss/{IndexIVFPQR.cpp → faiss/IndexIVFPQR.cpp} +3 -1
  52. data/vendor/faiss/{IndexIVFPQR.h → faiss/IndexIVFPQR.h} +0 -0
  53. data/vendor/faiss/{IndexIVFSpectralHash.cpp → faiss/IndexIVFSpectralHash.cpp} +1 -1
  54. data/vendor/faiss/{IndexIVFSpectralHash.h → faiss/IndexIVFSpectralHash.h} +0 -0
  55. data/vendor/faiss/{IndexLSH.cpp → faiss/IndexLSH.cpp} +0 -0
  56. data/vendor/faiss/{IndexLSH.h → faiss/IndexLSH.h} +0 -0
  57. data/vendor/faiss/{IndexLattice.cpp → faiss/IndexLattice.cpp} +0 -0
  58. data/vendor/faiss/{IndexLattice.h → faiss/IndexLattice.h} +0 -0
  59. data/vendor/faiss/{IndexPQ.cpp → faiss/IndexPQ.cpp} +6 -6
  60. data/vendor/faiss/{IndexPQ.h → faiss/IndexPQ.h} +3 -1
  61. data/vendor/faiss/{IndexPreTransform.cpp → faiss/IndexPreTransform.cpp} +0 -0
  62. data/vendor/faiss/{IndexPreTransform.h → faiss/IndexPreTransform.h} +0 -0
  63. data/vendor/faiss/{IndexReplicas.cpp → faiss/IndexReplicas.cpp} +102 -10
  64. data/vendor/faiss/{IndexReplicas.h → faiss/IndexReplicas.h} +6 -0
  65. data/vendor/faiss/{IndexScalarQuantizer.cpp → faiss/IndexScalarQuantizer.cpp} +3 -3
  66. data/vendor/faiss/{IndexScalarQuantizer.h → faiss/IndexScalarQuantizer.h} +0 -0
  67. data/vendor/faiss/{IndexShards.cpp → faiss/IndexShards.cpp} +37 -12
  68. data/vendor/faiss/{IndexShards.h → faiss/IndexShards.h} +3 -4
  69. data/vendor/faiss/{InvertedLists.cpp → faiss/InvertedLists.cpp} +2 -2
  70. data/vendor/faiss/{InvertedLists.h → faiss/InvertedLists.h} +1 -0
  71. data/vendor/faiss/{MatrixStats.cpp → faiss/MatrixStats.cpp} +0 -0
  72. data/vendor/faiss/{MatrixStats.h → faiss/MatrixStats.h} +0 -0
  73. data/vendor/faiss/{MetaIndexes.cpp → faiss/MetaIndexes.cpp} +5 -3
  74. data/vendor/faiss/{MetaIndexes.h → faiss/MetaIndexes.h} +0 -0
  75. data/vendor/faiss/{MetricType.h → faiss/MetricType.h} +0 -0
  76. data/vendor/faiss/{OnDiskInvertedLists.cpp → faiss/OnDiskInvertedLists.cpp} +141 -3
  77. data/vendor/faiss/{OnDiskInvertedLists.h → faiss/OnDiskInvertedLists.h} +27 -7
  78. data/vendor/faiss/{VectorTransform.cpp → faiss/VectorTransform.cpp} +4 -3
  79. data/vendor/faiss/{VectorTransform.h → faiss/VectorTransform.h} +0 -0
  80. data/vendor/faiss/{clone_index.cpp → faiss/clone_index.cpp} +0 -0
  81. data/vendor/faiss/{clone_index.h → faiss/clone_index.h} +0 -0
  82. data/vendor/faiss/{gpu → faiss/gpu}/GpuAutoTune.cpp +0 -0
  83. data/vendor/faiss/{gpu → faiss/gpu}/GpuAutoTune.h +0 -0
  84. data/vendor/faiss/{gpu → faiss/gpu}/GpuCloner.cpp +14 -14
  85. data/vendor/faiss/{gpu → faiss/gpu}/GpuCloner.h +6 -7
  86. data/vendor/faiss/{gpu → faiss/gpu}/GpuClonerOptions.cpp +0 -0
  87. data/vendor/faiss/{gpu → faiss/gpu}/GpuClonerOptions.h +0 -0
  88. data/vendor/faiss/{gpu → faiss/gpu}/GpuDistance.h +12 -4
  89. data/vendor/faiss/{gpu → faiss/gpu}/GpuFaissAssert.h +0 -0
  90. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndex.h +3 -9
  91. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexBinaryFlat.h +7 -7
  92. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexFlat.h +35 -10
  93. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVF.h +1 -2
  94. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFFlat.h +4 -3
  95. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFPQ.h +21 -4
  96. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFScalarQuantizer.h +4 -3
  97. data/vendor/faiss/{gpu → faiss/gpu}/GpuIndicesOptions.h +0 -0
  98. data/vendor/faiss/faiss/gpu/GpuResources.cpp +200 -0
  99. data/vendor/faiss/faiss/gpu/GpuResources.h +264 -0
  100. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +572 -0
  101. data/vendor/faiss/{gpu → faiss/gpu}/StandardGpuResources.h +83 -15
  102. data/vendor/faiss/{gpu → faiss/gpu}/impl/RemapIndices.cpp +0 -0
  103. data/vendor/faiss/{gpu → faiss/gpu}/impl/RemapIndices.h +0 -0
  104. data/vendor/faiss/{gpu → faiss/gpu}/perf/IndexWrapper-inl.h +1 -1
  105. data/vendor/faiss/{gpu → faiss/gpu}/perf/IndexWrapper.h +1 -1
  106. data/vendor/faiss/{gpu → faiss/gpu}/perf/PerfClustering.cpp +1 -1
  107. data/vendor/faiss/{gpu → faiss/gpu}/perf/PerfIVFPQAdd.cpp +0 -0
  108. data/vendor/faiss/{gpu → faiss/gpu}/perf/WriteIndex.cpp +0 -0
  109. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexBinaryFlat.cpp +0 -0
  110. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexFlat.cpp +1 -1
  111. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexIVFFlat.cpp +0 -0
  112. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexIVFPQ.cpp +141 -52
  113. data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuMemoryException.cpp +0 -0
  114. data/vendor/faiss/{gpu → faiss/gpu}/test/TestUtils.cpp +4 -2
  115. data/vendor/faiss/{gpu → faiss/gpu}/test/TestUtils.h +0 -0
  116. data/vendor/faiss/{gpu → faiss/gpu}/test/demo_ivfpq_indexing_gpu.cpp +7 -5
  117. data/vendor/faiss/{gpu → faiss/gpu}/utils/DeviceUtils.h +1 -1
  118. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +213 -0
  119. data/vendor/faiss/{gpu → faiss/gpu}/utils/StackDeviceMemory.h +25 -40
  120. data/vendor/faiss/{gpu → faiss/gpu}/utils/StaticUtils.h +0 -0
  121. data/vendor/faiss/{gpu → faiss/gpu}/utils/Timer.cpp +0 -0
  122. data/vendor/faiss/{gpu → faiss/gpu}/utils/Timer.h +0 -0
  123. data/vendor/faiss/{impl → faiss/impl}/AuxIndexStructures.cpp +1 -0
  124. data/vendor/faiss/{impl → faiss/impl}/AuxIndexStructures.h +3 -1
  125. data/vendor/faiss/{impl → faiss/impl}/FaissAssert.h +1 -0
  126. data/vendor/faiss/{impl → faiss/impl}/FaissException.cpp +26 -0
  127. data/vendor/faiss/{impl → faiss/impl}/FaissException.h +4 -0
  128. data/vendor/faiss/{impl → faiss/impl}/HNSW.cpp +26 -26
  129. data/vendor/faiss/{impl → faiss/impl}/HNSW.h +19 -11
  130. data/vendor/faiss/{impl → faiss/impl}/PolysemousTraining.cpp +1 -1
  131. data/vendor/faiss/{impl → faiss/impl}/PolysemousTraining.h +1 -1
  132. data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer-inl.h +0 -1
  133. data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer.cpp +9 -9
  134. data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer.h +0 -0
  135. data/vendor/faiss/{impl → faiss/impl}/ScalarQuantizer.cpp +63 -39
  136. data/vendor/faiss/{impl → faiss/impl}/ScalarQuantizer.h +1 -1
  137. data/vendor/faiss/{impl → faiss/impl}/ThreadedIndex-inl.h +0 -0
  138. data/vendor/faiss/{impl → faiss/impl}/ThreadedIndex.h +0 -0
  139. data/vendor/faiss/{impl → faiss/impl}/index_read.cpp +99 -116
  140. data/vendor/faiss/{impl → faiss/impl}/index_write.cpp +15 -50
  141. data/vendor/faiss/{impl → faiss/impl}/io.cpp +15 -10
  142. data/vendor/faiss/{impl → faiss/impl}/io.h +22 -8
  143. data/vendor/faiss/faiss/impl/io_macros.h +57 -0
  144. data/vendor/faiss/{impl → faiss/impl}/lattice_Zn.cpp +52 -36
  145. data/vendor/faiss/{impl → faiss/impl}/lattice_Zn.h +3 -3
  146. data/vendor/faiss/faiss/impl/platform_macros.h +24 -0
  147. data/vendor/faiss/{index_factory.cpp → faiss/index_factory.cpp} +33 -12
  148. data/vendor/faiss/{index_factory.h → faiss/index_factory.h} +0 -0
  149. data/vendor/faiss/{index_io.h → faiss/index_io.h} +55 -1
  150. data/vendor/faiss/faiss/python/python_callbacks.cpp +112 -0
  151. data/vendor/faiss/faiss/python/python_callbacks.h +45 -0
  152. data/vendor/faiss/{utils → faiss/utils}/Heap.cpp +5 -5
  153. data/vendor/faiss/{utils → faiss/utils}/Heap.h +1 -3
  154. data/vendor/faiss/{utils → faiss/utils}/WorkerThread.cpp +0 -0
  155. data/vendor/faiss/{utils → faiss/utils}/WorkerThread.h +0 -0
  156. data/vendor/faiss/{utils → faiss/utils}/distances.cpp +28 -13
  157. data/vendor/faiss/{utils → faiss/utils}/distances.h +2 -1
  158. data/vendor/faiss/{utils → faiss/utils}/distances_simd.cpp +5 -5
  159. data/vendor/faiss/{utils → faiss/utils}/extra_distances.cpp +8 -7
  160. data/vendor/faiss/{utils → faiss/utils}/extra_distances.h +0 -0
  161. data/vendor/faiss/{utils → faiss/utils}/hamming-inl.h +1 -3
  162. data/vendor/faiss/{utils → faiss/utils}/hamming.cpp +8 -7
  163. data/vendor/faiss/{utils → faiss/utils}/hamming.h +7 -1
  164. data/vendor/faiss/{utils → faiss/utils}/random.cpp +5 -5
  165. data/vendor/faiss/{utils → faiss/utils}/random.h +0 -0
  166. data/vendor/faiss/{utils → faiss/utils}/utils.cpp +27 -28
  167. data/vendor/faiss/{utils → faiss/utils}/utils.h +4 -0
  168. data/vendor/faiss/misc/test_blas.cpp +4 -1
  169. data/vendor/faiss/tests/test_binary_flat.cpp +0 -2
  170. data/vendor/faiss/tests/test_dealloc_invlists.cpp +6 -1
  171. data/vendor/faiss/tests/test_ivfpq_codec.cpp +4 -1
  172. data/vendor/faiss/tests/test_ivfpq_indexing.cpp +6 -4
  173. data/vendor/faiss/tests/test_lowlevel_ivf.cpp +12 -5
  174. data/vendor/faiss/tests/test_merge.cpp +6 -3
  175. data/vendor/faiss/tests/test_ondisk_ivf.cpp +7 -2
  176. data/vendor/faiss/tests/test_pairs_decoding.cpp +5 -1
  177. data/vendor/faiss/tests/test_params_override.cpp +7 -2
  178. data/vendor/faiss/tests/test_sliding_ivf.cpp +10 -4
  179. data/vendor/faiss/tutorial/cpp/1-Flat.cpp +14 -8
  180. data/vendor/faiss/tutorial/cpp/2-IVFFlat.cpp +11 -7
  181. data/vendor/faiss/tutorial/cpp/3-IVFPQ.cpp +12 -7
  182. data/vendor/faiss/tutorial/cpp/4-GPU.cpp +6 -3
  183. data/vendor/faiss/tutorial/cpp/5-Multiple-GPUs.cpp +7 -3
  184. metadata +154 -153
  185. data/vendor/faiss/gpu/GpuResources.cpp +0 -52
  186. data/vendor/faiss/gpu/GpuResources.h +0 -73
  187. data/vendor/faiss/gpu/StandardGpuResources.cpp +0 -303
  188. data/vendor/faiss/gpu/utils/DeviceMemory.cpp +0 -77
  189. data/vendor/faiss/gpu/utils/DeviceMemory.h +0 -71
  190. data/vendor/faiss/gpu/utils/MemorySpace.cpp +0 -89
  191. data/vendor/faiss/gpu/utils/MemorySpace.h +0 -44
  192. data/vendor/faiss/gpu/utils/StackDeviceMemory.cpp +0 -239
@@ -29,7 +29,7 @@ struct IOReader {
29
29
  // name that can be used in error messages
30
30
  std::string name;
31
31
 
32
- // fread
32
+ // fread. Returns number of items read or 0 in case of EOF.
33
33
  virtual size_t operator()(
34
34
  void *ptr, size_t size, size_t nitems) = 0;
35
35
 
@@ -43,7 +43,7 @@ struct IOWriter {
43
43
  // name that can be used in error messages
44
44
  std::string name;
45
45
 
46
- // fwrite
46
+ // fwrite. Return number of items written
47
47
  virtual size_t operator()(
48
48
  const void *ptr, size_t size, size_t nitems) = 0;
49
49
 
@@ -97,6 +97,10 @@ struct FileIOWriter: IOWriter {
97
97
 
98
98
  /*******************************************************
99
99
  * Buffered reader + writer
100
+ *
101
+ * They attempt to read and write only buffers of size bsz to the
102
+ * underlying reader or writer. This is done by splitting or merging
103
+ * the read/write functions.
100
104
  *******************************************************/
101
105
 
102
106
 
@@ -105,24 +109,32 @@ struct FileIOWriter: IOWriter {
105
109
  struct BufferedIOReader: IOReader {
106
110
 
107
111
  IOReader *reader;
108
- size_t bsz, totsz, ofs;
112
+ size_t bsz;
113
+ size_t ofs; ///< offset in input stream
114
+ size_t ofs2; ///< number of bytes returned to caller
109
115
  size_t b0, b1; ///< range of available bytes in the buffer
110
116
  std::vector<char> buffer;
111
117
 
112
- BufferedIOReader(IOReader *reader, size_t bsz,
113
- size_t totsz=(size_t)(-1));
118
+ /**
119
+ * @param bsz buffer size (bytes). Reads will be done by batched of
120
+ * this size
121
+ */
122
+ explicit BufferedIOReader(IOReader *reader, size_t bsz = 1024 * 1024);
114
123
 
115
124
  size_t operator()(void *ptr, size_t size, size_t nitems) override;
116
125
  };
117
126
 
127
+
118
128
  struct BufferedIOWriter: IOWriter {
119
129
 
120
130
  IOWriter *writer;
121
- size_t bsz, ofs;
122
- size_t b0; ///< amount of data in buffer
131
+ size_t bsz;
132
+ size_t ofs;
133
+ size_t ofs2; ///< number of bytes received from caller
134
+ size_t b0; ///< amount of data in buffer
123
135
  std::vector<char> buffer;
124
136
 
125
- BufferedIOWriter(IOWriter *writer, size_t bsz);
137
+ explicit BufferedIOWriter(IOWriter *writer, size_t bsz = 1024 * 1024);
126
138
 
127
139
  size_t operator()(const void *ptr, size_t size, size_t nitems) override;
128
140
 
@@ -132,5 +144,7 @@ struct BufferedIOWriter: IOWriter {
132
144
 
133
145
  /// cast a 4-character string to a uint32_t that can be written and read easily
134
146
  uint32_t fourcc (const char sx[4]);
147
+ uint32_t fourcc (const std::string & sx);
148
+
135
149
 
136
150
  } // namespace faiss
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ /*************************************************************
11
+ * I/O macros
12
+ *
13
+ * we use macros so that we have a line number to report in abort
14
+ * (). This makes debugging a lot easier. The IOReader or IOWriter is
15
+ * always called f and thus is not passed in as a macro parameter.
16
+ **************************************************************/
17
+
18
+
19
+ #define READANDCHECK(ptr, n) { \
20
+ size_t ret = (*f)(ptr, sizeof(*(ptr)), n); \
21
+ FAISS_THROW_IF_NOT_FMT(ret == (n), \
22
+ "read error in %s: %zd != %zd (%s)", \
23
+ f->name.c_str(), ret, size_t(n), strerror(errno)); \
24
+ }
25
+
26
+ #define READ1(x) READANDCHECK(&(x), 1)
27
+
28
+ // will fail if we write 256G of data at once...
29
+ #define READVECTOR(vec) \
30
+ { \
31
+ size_t size; \
32
+ READANDCHECK(&size, 1); \
33
+ FAISS_THROW_IF_NOT(size >= 0 && size < (uint64_t{1} << 40)); \
34
+ (vec).resize(size); \
35
+ READANDCHECK((vec).data(), size); \
36
+ }
37
+
38
+ #define READSTRING(s) { \
39
+ size_t size = (s).size (); \
40
+ WRITEANDCHECK (&size, 1); \
41
+ WRITEANDCHECK ((s).c_str(), size); \
42
+ }
43
+
44
+ #define WRITEANDCHECK(ptr, n) { \
45
+ size_t ret = (*f)(ptr, sizeof(*(ptr)), n); \
46
+ FAISS_THROW_IF_NOT_FMT(ret == (n), \
47
+ "write error in %s: %zd != %zd (%s)", \
48
+ f->name.c_str(), ret, size_t(n), strerror(errno)); \
49
+ }
50
+
51
+ #define WRITE1(x) WRITEANDCHECK(&(x), 1)
52
+
53
+ #define WRITEVECTOR(vec) { \
54
+ size_t size = (vec).size (); \
55
+ WRITEANDCHECK (&size, 1); \
56
+ WRITEANDCHECK ((vec).data (), size); \
57
+ }
@@ -21,6 +21,22 @@
21
21
 
22
22
  #include <faiss/utils/distances.h>
23
23
 
24
+ #ifdef _MSC_VER
25
+
26
+ #include <intrin.h>
27
+
28
+ static inline int __builtin_ctzll(uint64_t x) {
29
+ unsigned long ret;
30
+ _BitScanForward64(&ret, x);
31
+ return (int)ret;
32
+ }
33
+
34
+ static inline int __builtin_clzll(uint64_t x) {
35
+ return (int)__lzcnt64(x);
36
+ }
37
+
38
+ #endif // _MSC_VER
39
+
24
40
  namespace faiss {
25
41
 
26
42
  /********************************************
@@ -102,7 +118,7 @@ int decode_comb_1 (uint64_t *n, int k1, int r) {
102
118
  }
103
119
 
104
120
  // optimized version for < 64 bits
105
- long repeats_encode_64 (
121
+ uint64_t repeats_encode_64 (
106
122
  const std::vector<Repeat> & repeats,
107
123
  int dim, const float *c)
108
124
  {
@@ -115,12 +131,12 @@ long repeats_encode_64 (
115
131
  uint64_t tosee = ~coded;
116
132
  for(;;) {
117
133
  // directly jump to next available slot.
118
- int i = __builtin_ctzl(tosee);
119
- tosee &= ~(1UL << i) ;
134
+ int i = __builtin_ctzll(tosee);
135
+ tosee &= ~(uint64_t{1} << i) ;
120
136
  if (c[i] == r->val) {
121
137
  code_comb += comb(rank, occ + 1);
122
138
  occ++;
123
- coded |= 1UL << i;
139
+ coded |= uint64_t{1} << i;
124
140
  if (occ == r->n) break;
125
141
  }
126
142
  rank++;
@@ -148,13 +164,13 @@ void repeats_decode_64(
148
164
  int occ = 0;
149
165
  int rank = nfree;
150
166
  int next_rank = decode_comb_1 (&code_comb, r->n, rank);
151
- uint64_t tosee = ((1UL << dim) - 1) ^ decoded;
167
+ uint64_t tosee = ((uint64_t{1} << dim) - 1) ^ decoded;
152
168
  for(;;) {
153
- int i = 63 - __builtin_clzl(tosee);
154
- tosee &= ~(1UL << i);
169
+ int i = 63 - __builtin_clzll(tosee);
170
+ tosee &= ~(uint64_t{1} << i);
155
171
  rank--;
156
172
  if (rank == next_rank) {
157
- decoded |= 1UL << i;
173
+ decoded |= uint64_t{1} << i;
158
174
  c[i] = r->val;
159
175
  occ++;
160
176
  if (occ == r->n) break;
@@ -190,9 +206,9 @@ Repeats::Repeats (int dim, const float *c): dim(dim)
190
206
  }
191
207
 
192
208
 
193
- long Repeats::count () const
209
+ uint64_t Repeats::count () const
194
210
  {
195
- long accu = 1;
211
+ uint64_t accu = 1;
196
212
  int remain = dim;
197
213
  for (int i = 0; i < repeats.size(); i++) {
198
214
  accu *= comb(remain, repeats[i].n);
@@ -204,7 +220,7 @@ long Repeats::count () const
204
220
 
205
221
 
206
222
  // version with a bool vector that works for > 64 dim
207
- long Repeats::encode(const float *c) const
223
+ uint64_t Repeats::encode(const float *c) const
208
224
  {
209
225
  if (dim < 64) {
210
226
  return repeats_encode_64 (repeats, dim, c);
@@ -306,20 +322,20 @@ void EnumeratedVectors::decode_multi(size_t n, const uint64_t * codes,
306
322
  void EnumeratedVectors::find_nn (
307
323
  size_t nc, const uint64_t * codes,
308
324
  size_t nq, const float *xq,
309
- long *labels, float *distances)
325
+ int64_t *labels, float *distances)
310
326
  {
311
- for (long i = 0; i < nq; i++) {
327
+ for (size_t i = 0; i < nq; i++) {
312
328
  distances[i] = -1e20;
313
329
  labels[i] = -1;
314
330
  }
315
331
 
316
- float c[dim];
317
- for(long i = 0; i < nc; i++) {
332
+ std::vector<float> c(dim);
333
+ for(size_t i = 0; i < nc; i++) {
318
334
  uint64_t code = codes[nc];
319
- decode(code, c);
320
- for (long j = 0; j < nq; j++) {
335
+ decode(code, c.data());
336
+ for (size_t j = 0; j < nq; j++) {
321
337
  const float *x = xq + j * dim;
322
- float dis = fvec_inner_product(x, c, dim);
338
+ float dis = fvec_inner_product(x, c.data(), dim);
323
339
  if (dis > distances[j]) {
324
340
  distances[j] = dis;
325
341
  labels[j] = i;
@@ -341,9 +357,9 @@ ZnSphereSearch::ZnSphereSearch(int dim, int r2): dimS(dim), r2(r2) {
341
357
  }
342
358
 
343
359
  float ZnSphereSearch::search(const float *x, float *c) const {
344
- float tmp[dimS * 2];
345
- int tmp_int[dimS];
346
- return search(x, c, tmp, tmp_int);
360
+ std::vector<float> tmp(dimS * 2);
361
+ std::vector<int> tmp_int(dimS);
362
+ return search(x, c, tmp.data(), tmp_int.data());
347
363
  }
348
364
 
349
365
  float ZnSphereSearch::search(const float *x, float *c,
@@ -430,19 +446,19 @@ ZnSphereCodec::ZnSphereCodec(int dim, int r2):
430
446
  }
431
447
 
432
448
  uint64_t ZnSphereCodec::search_and_encode(const float *x) const {
433
- float tmp[dim * 2];
434
- int tmp_int[dim];
449
+ std::vector<float> tmp(dim * 2);
450
+ std::vector<int> tmp_int(dim);
435
451
  int ano; // atom number
436
- float c[dim];
437
- search(x, c, tmp, tmp_int, &ano);
452
+ std::vector<float> c(dim);
453
+ search(x, c.data(), tmp.data(), tmp_int.data(), &ano);
438
454
  uint64_t signs = 0;
439
- float cabs[dim];
455
+ std::vector<float> cabs(dim);
440
456
  int nnz = 0;
441
457
  for (int i = 0; i < dim; i++) {
442
458
  cabs[i] = fabs(c[i]);
443
459
  if (c[i] != 0) {
444
460
  if (c[i] < 0) {
445
- signs |= 1UL << nnz;
461
+ signs |= uint64_t{1} << nnz;
446
462
  }
447
463
  nnz ++;
448
464
  }
@@ -450,7 +466,7 @@ uint64_t ZnSphereCodec::search_and_encode(const float *x) const {
450
466
  const CodeSegment &cs = code_segments[ano];
451
467
  assert(nnz == cs.signbits);
452
468
  uint64_t code = cs.c0 + signs;
453
- code += cs.encode(cabs) << cs.signbits;
469
+ code += cs.encode(cabs.data()) << cs.signbits;
454
470
  return code;
455
471
  }
456
472
 
@@ -560,13 +576,13 @@ ZnSphereCodecRec::ZnSphereCodecRec(int dim, int r2):
560
576
  std::vector<float> &cache = decode_cache[r2sub];
561
577
  int dimsub = (1 << cache_level);
562
578
  cache.resize (nvi * dimsub);
563
- float c[dim];
579
+ std::vector<float> c(dim);
564
580
  uint64_t code0 = get_nv_cum(cache_level + 1, r2,
565
581
  r2 - r2sub);
566
582
  for (int i = 0; i < nvi; i++) {
567
- decode(i + code0, c);
568
- memcpy(&cache[i * dimsub], c + dim - dimsub,
569
- dimsub * sizeof(*c));
583
+ decode(i + code0, c.data());
584
+ memcpy(&cache[i * dimsub], c.data() + dim - dimsub,
585
+ dimsub * sizeof(*c.data()));
570
586
  }
571
587
  }
572
588
  decode_cache_ld = cache_level;
@@ -581,8 +597,8 @@ uint64_t ZnSphereCodecRec::encode(const float *c) const
581
597
 
582
598
  uint64_t ZnSphereCodecRec::encode_centroid(const float *c) const
583
599
  {
584
- uint64_t codes[dim];
585
- int norm2s[dim];
600
+ std::vector<uint64_t> codes(dim);
601
+ std::vector<int> norm2s(dim);
586
602
  for(int i = 0; i < dim; i++) {
587
603
  if (c[i] == 0) {
588
604
  codes[i] = 0;
@@ -617,8 +633,8 @@ uint64_t ZnSphereCodecRec::encode_centroid(const float *c) const
617
633
 
618
634
  void ZnSphereCodecRec::decode(uint64_t code, float *c) const
619
635
  {
620
- uint64_t codes[dim];
621
- int norm2s[dim];
636
+ std::vector<uint64_t> codes(dim);
637
+ std::vector<int> norm2s(dim);
622
638
  codes[0] = code;
623
639
  norm2s[0] = r2;
624
640
 
@@ -80,7 +80,7 @@ struct EnumeratedVectors {
80
80
  // (decodes and computes distances)
81
81
  void find_nn (size_t n, const uint64_t * codes,
82
82
  size_t nq, const float *xq,
83
- long *idx, float *dis);
83
+ int64_t *idx, float *dis);
84
84
 
85
85
  virtual ~EnumeratedVectors() {}
86
86
 
@@ -103,9 +103,9 @@ struct Repeats {
103
103
  Repeats(int dim = 0, const float *c = nullptr);
104
104
 
105
105
  // count number of possible codes for this atom
106
- long count() const;
106
+ uint64_t count() const;
107
107
 
108
- long encode(const float *c) const;
108
+ uint64_t encode(const float *c) const;
109
109
 
110
110
  void decode(uint64_t code, float *c) const;
111
111
  };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #ifdef _MSC_VER
11
+
12
+ #ifdef FAISS_MAIN_LIB
13
+ #define FAISS_API __declspec(dllexport)
14
+ #else // _FAISS_MAIN_LIB
15
+ #define FAISS_API __declspec(dllimport)
16
+ #endif // FAISS_MAIN_LIB
17
+
18
+ #define __PRETTY_FUNCTION__ __FUNCSIG__
19
+
20
+ #else
21
+
22
+ #define FAISS_API
23
+
24
+ #endif // _MSC_VER
@@ -13,9 +13,9 @@
13
13
 
14
14
  #include <faiss/AutoTune.h>
15
15
 
16
+ #include <cinttypes>
16
17
  #include <cmath>
17
18
 
18
-
19
19
  #include <faiss/impl/FaissAssert.h>
20
20
  #include <faiss/utils/utils.h>
21
21
  #include <faiss/utils/random.h>
@@ -38,6 +38,7 @@
38
38
  #include <faiss/IndexBinaryFlat.h>
39
39
  #include <faiss/IndexBinaryHNSW.h>
40
40
  #include <faiss/IndexBinaryIVF.h>
41
+ #include <faiss/IndexBinaryHash.h>
41
42
 
42
43
  namespace faiss {
43
44
 
@@ -81,14 +82,14 @@ Index *index_factory (int d, const char *description_in, MetricType metric)
81
82
 
82
83
  ScopeDeleter1<Index> del_coarse_quantizer, del_index;
83
84
 
84
- char description[strlen(description_in) + 1];
85
+ std::string description(description_in);
85
86
  char *ptr;
86
- memcpy (description, description_in, strlen(description_in) + 1);
87
87
 
88
88
  int64_t ncentroids = -1;
89
89
  bool use_2layer = false;
90
+ int hnsw_M = -1;
90
91
 
91
- for (char *tok = strtok_r (description, " ,", &ptr);
92
+ for (char *tok = strtok_r (&description[0], " ,", &ptr);
92
93
  tok;
93
94
  tok = strtok_r (nullptr, " ,", &ptr)) {
94
95
  int d_out, opq_M, nbit, M, M2, pq_m, ncent, r2;
@@ -138,12 +139,11 @@ Index *index_factory (int d, const char *description_in, MetricType metric)
138
139
 
139
140
  // coarse quantizers
140
141
  } else if (!coarse_quantizer &&
141
- sscanf (tok, "IVF%ld_HNSW%d", &ncentroids, &M) == 2) {
142
- FAISS_THROW_IF_NOT (metric == METRIC_L2);
142
+ sscanf (tok, "IVF%" PRId64 "_HNSW%d", &ncentroids, &M) == 2) {
143
143
  coarse_quantizer_1 = new IndexHNSWFlat (d, M);
144
144
 
145
145
  } else if (!coarse_quantizer &&
146
- sscanf (tok, "IVF%ld", &ncentroids) == 1) {
146
+ sscanf (tok, "IVF%" PRId64, &ncentroids) == 1) {
147
147
  if (metric == METRIC_L2) {
148
148
  coarse_quantizer_1 = new IndexFlatL2 (d);
149
149
  } else {
@@ -164,7 +164,7 @@ Index *index_factory (int d, const char *description_in, MetricType metric)
164
164
  use_2layer = true;
165
165
 
166
166
  } else if (!coarse_quantizer &&
167
- sscanf (tok, "Residual%ld", &ncentroids) == 1) {
167
+ sscanf (tok, "Residual%" PRId64, &ncentroids) == 1) {
168
168
  coarse_quantizer_1 = new IndexFlatL2 (d);
169
169
  use_2layer = true;
170
170
 
@@ -186,6 +186,8 @@ Index *index_factory (int d, const char *description_in, MetricType metric)
186
186
  del_coarse_quantizer.release ();
187
187
  index_ivf->own_fields = true;
188
188
  index_1 = index_ivf;
189
+ } else if (hnsw_M > 0) {
190
+ index_1 = new IndexHNSWFlat (d, hnsw_M, metric);
189
191
  } else {
190
192
  FAISS_THROW_IF_NOT_MSG (stok != "FlatDedup",
191
193
  "dedup supported only for IVFFlat");
@@ -209,6 +211,8 @@ Index *index_factory (int d, const char *description_in, MetricType metric)
209
211
  del_coarse_quantizer.release ();
210
212
  index_ivf->own_fields = true;
211
213
  index_1 = index_ivf;
214
+ } else if (hnsw_M > 0) {
215
+ index_1 = new IndexHNSWSQ(d, qt, hnsw_M, metric);
212
216
  } else {
213
217
  index_1 = new IndexScalarQuantizer (d, qt, metric);
214
218
  }
@@ -248,6 +252,11 @@ Index *index_factory (int d, const char *description_in, MetricType metric)
248
252
  index_2l->q1.own_fields = true;
249
253
  index_1 = index_2l;
250
254
  }
255
+ } else if (hnsw_M > 0) {
256
+ IndexHNSWPQ *ipq = new IndexHNSWPQ(d, M, hnsw_M);
257
+ dynamic_cast<IndexPQ*>(ipq->storage)->do_polysemous_training =
258
+ do_polysemous_training;
259
+ index_1 = ipq;
251
260
  } else {
252
261
  IndexPQ *index_pq = new IndexPQ (d, M, nbit, metric);
253
262
  index_pq->do_polysemous_training = do_polysemous_training;
@@ -272,13 +281,14 @@ Index *index_factory (int d, const char *description_in, MetricType metric)
272
281
  } else if (!index &&
273
282
  sscanf (tok, "HNSW%d_PQ%d", &M, &pq_m) == 2) {
274
283
  index_1 = new IndexHNSWPQ (d, pq_m, M);
275
- } else if (!index &&
276
- sscanf (tok, "HNSW%d", &M) == 1) {
277
- index_1 = new IndexHNSWFlat (d, M);
278
284
  } else if (!index &&
279
285
  sscanf (tok, "HNSW%d_SQ%d", &M, &pq_m) == 2 &&
280
286
  pq_m == 8) {
281
287
  index_1 = new IndexHNSWSQ (d, ScalarQuantizer::QT_8bit, M);
288
+ } else if (!index &&
289
+ sscanf (tok, "HNSW%d", &M) == 1) {
290
+ hnsw_M = M;
291
+ // here it is unclear what we want: HNSW flat or HNSWx,Y ?
282
292
  } else if (!index && (stok == "LSH" || stok == "LSHr" ||
283
293
  stok == "LSHrt" || stok == "LSHt")) {
284
294
  bool rotate_data = strstr(tok, "r") != nullptr;
@@ -318,6 +328,11 @@ Index *index_factory (int d, const char *description_in, MetricType metric)
318
328
  }
319
329
  }
320
330
 
331
+ if (!index && hnsw_M > 0) {
332
+ index = new IndexHNSWFlat (d, hnsw_M, metric);
333
+ del_index.set (index);
334
+ }
335
+
321
336
  FAISS_THROW_IF_NOT_FMT(index, "description %s did not generate an index",
322
337
  description_in);
323
338
 
@@ -355,7 +370,7 @@ IndexBinary *index_binary_factory(int d, const char *description)
355
370
  IndexBinary *index = nullptr;
356
371
 
357
372
  int ncentroids = -1;
358
- int M;
373
+ int M, nhash, b;
359
374
 
360
375
  if (sscanf(description, "BIVF%d_HNSW%d", &ncentroids, &M) == 2) {
361
376
  IndexBinaryIVF *index_ivf = new IndexBinaryIVF(
@@ -375,6 +390,12 @@ IndexBinary *index_binary_factory(int d, const char *description)
375
390
  IndexBinaryHNSW *index_hnsw = new IndexBinaryHNSW(d, M);
376
391
  index = index_hnsw;
377
392
 
393
+ } else if (sscanf(description, "BHash%dx%d", &nhash, &b) == 2) {
394
+ index = new IndexBinaryMultiHash (d, nhash, b);
395
+
396
+ } else if (sscanf(description, "BHash%d", &b) == 1) {
397
+ index = new IndexBinaryHash (d, b);
398
+
378
399
  } else if (std::string(description) == "BFlat") {
379
400
  index = new IndexBinaryFlat(d);
380
401