faiss 0.3.1 → 0.3.3

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 (293) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/LICENSE.txt +1 -1
  4. data/lib/faiss/version.rb +1 -1
  5. data/vendor/faiss/faiss/AutoTune.cpp +2 -2
  6. data/vendor/faiss/faiss/AutoTune.h +3 -3
  7. data/vendor/faiss/faiss/Clustering.cpp +37 -6
  8. data/vendor/faiss/faiss/Clustering.h +12 -3
  9. data/vendor/faiss/faiss/IVFlib.cpp +6 -3
  10. data/vendor/faiss/faiss/IVFlib.h +2 -2
  11. data/vendor/faiss/faiss/Index.cpp +6 -2
  12. data/vendor/faiss/faiss/Index.h +30 -8
  13. data/vendor/faiss/faiss/Index2Layer.cpp +2 -2
  14. data/vendor/faiss/faiss/Index2Layer.h +2 -2
  15. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +7 -7
  16. data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +2 -2
  17. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +14 -16
  18. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.h +2 -2
  19. data/vendor/faiss/faiss/IndexBinary.cpp +13 -2
  20. data/vendor/faiss/faiss/IndexBinary.h +8 -2
  21. data/vendor/faiss/faiss/IndexBinaryFlat.cpp +2 -3
  22. data/vendor/faiss/faiss/IndexBinaryFlat.h +2 -2
  23. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +2 -2
  24. data/vendor/faiss/faiss/IndexBinaryFromFloat.h +2 -2
  25. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +2 -7
  26. data/vendor/faiss/faiss/IndexBinaryHNSW.h +3 -3
  27. data/vendor/faiss/faiss/IndexBinaryHash.cpp +2 -3
  28. data/vendor/faiss/faiss/IndexBinaryHash.h +2 -2
  29. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +3 -3
  30. data/vendor/faiss/faiss/IndexBinaryIVF.h +2 -2
  31. data/vendor/faiss/faiss/IndexFastScan.cpp +32 -18
  32. data/vendor/faiss/faiss/IndexFastScan.h +11 -2
  33. data/vendor/faiss/faiss/IndexFlat.cpp +13 -10
  34. data/vendor/faiss/faiss/IndexFlat.h +2 -2
  35. data/vendor/faiss/faiss/IndexFlatCodes.cpp +170 -7
  36. data/vendor/faiss/faiss/IndexFlatCodes.h +25 -5
  37. data/vendor/faiss/faiss/IndexHNSW.cpp +156 -96
  38. data/vendor/faiss/faiss/IndexHNSW.h +54 -5
  39. data/vendor/faiss/faiss/IndexIDMap.cpp +19 -3
  40. data/vendor/faiss/faiss/IndexIDMap.h +5 -2
  41. data/vendor/faiss/faiss/IndexIVF.cpp +5 -6
  42. data/vendor/faiss/faiss/IndexIVF.h +13 -4
  43. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +21 -7
  44. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +5 -2
  45. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +3 -14
  46. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +2 -4
  47. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +201 -91
  48. data/vendor/faiss/faiss/IndexIVFFastScan.h +33 -9
  49. data/vendor/faiss/faiss/IndexIVFFlat.cpp +2 -2
  50. data/vendor/faiss/faiss/IndexIVFFlat.h +2 -2
  51. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +2 -2
  52. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.h +2 -2
  53. data/vendor/faiss/faiss/IndexIVFPQ.cpp +3 -6
  54. data/vendor/faiss/faiss/IndexIVFPQ.h +2 -2
  55. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +7 -14
  56. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +2 -4
  57. data/vendor/faiss/faiss/IndexIVFPQR.cpp +2 -2
  58. data/vendor/faiss/faiss/IndexIVFPQR.h +2 -2
  59. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +2 -3
  60. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +2 -2
  61. data/vendor/faiss/faiss/IndexLSH.cpp +2 -3
  62. data/vendor/faiss/faiss/IndexLSH.h +2 -2
  63. data/vendor/faiss/faiss/IndexLattice.cpp +3 -21
  64. data/vendor/faiss/faiss/IndexLattice.h +5 -24
  65. data/vendor/faiss/faiss/IndexNNDescent.cpp +2 -31
  66. data/vendor/faiss/faiss/IndexNNDescent.h +3 -3
  67. data/vendor/faiss/faiss/IndexNSG.cpp +2 -5
  68. data/vendor/faiss/faiss/IndexNSG.h +3 -3
  69. data/vendor/faiss/faiss/IndexNeuralNetCodec.cpp +56 -0
  70. data/vendor/faiss/faiss/IndexNeuralNetCodec.h +49 -0
  71. data/vendor/faiss/faiss/IndexPQ.cpp +26 -26
  72. data/vendor/faiss/faiss/IndexPQ.h +2 -2
  73. data/vendor/faiss/faiss/IndexPQFastScan.cpp +2 -5
  74. data/vendor/faiss/faiss/IndexPQFastScan.h +2 -11
  75. data/vendor/faiss/faiss/IndexPreTransform.cpp +2 -2
  76. data/vendor/faiss/faiss/IndexPreTransform.h +3 -3
  77. data/vendor/faiss/faiss/IndexRefine.cpp +46 -9
  78. data/vendor/faiss/faiss/IndexRefine.h +9 -2
  79. data/vendor/faiss/faiss/IndexReplicas.cpp +2 -2
  80. data/vendor/faiss/faiss/IndexReplicas.h +2 -2
  81. data/vendor/faiss/faiss/IndexRowwiseMinMax.cpp +2 -2
  82. data/vendor/faiss/faiss/IndexRowwiseMinMax.h +2 -2
  83. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +5 -4
  84. data/vendor/faiss/faiss/IndexScalarQuantizer.h +2 -2
  85. data/vendor/faiss/faiss/IndexShards.cpp +2 -2
  86. data/vendor/faiss/faiss/IndexShards.h +2 -2
  87. data/vendor/faiss/faiss/IndexShardsIVF.cpp +2 -2
  88. data/vendor/faiss/faiss/IndexShardsIVF.h +2 -2
  89. data/vendor/faiss/faiss/MatrixStats.cpp +2 -2
  90. data/vendor/faiss/faiss/MatrixStats.h +2 -2
  91. data/vendor/faiss/faiss/MetaIndexes.cpp +2 -3
  92. data/vendor/faiss/faiss/MetaIndexes.h +2 -2
  93. data/vendor/faiss/faiss/MetricType.h +9 -4
  94. data/vendor/faiss/faiss/VectorTransform.cpp +2 -2
  95. data/vendor/faiss/faiss/VectorTransform.h +2 -2
  96. data/vendor/faiss/faiss/clone_index.cpp +2 -2
  97. data/vendor/faiss/faiss/clone_index.h +2 -2
  98. data/vendor/faiss/faiss/cppcontrib/SaDecodeKernels.h +2 -2
  99. data/vendor/faiss/faiss/cppcontrib/detail/CoarseBitType.h +2 -2
  100. data/vendor/faiss/faiss/cppcontrib/detail/UintReader.h +97 -19
  101. data/vendor/faiss/faiss/cppcontrib/factory_tools.cpp +192 -0
  102. data/vendor/faiss/faiss/cppcontrib/factory_tools.h +29 -0
  103. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-avx2-inl.h +2 -2
  104. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-inl.h +85 -32
  105. data/vendor/faiss/faiss/cppcontrib/sa_decode/Level2-neon-inl.h +2 -2
  106. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMax-inl.h +2 -2
  107. data/vendor/faiss/faiss/cppcontrib/sa_decode/MinMaxFP16-inl.h +2 -2
  108. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-avx2-inl.h +2 -2
  109. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-inl.h +2 -2
  110. data/vendor/faiss/faiss/cppcontrib/sa_decode/PQ-neon-inl.h +2 -2
  111. data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +2 -5
  112. data/vendor/faiss/faiss/gpu/GpuAutoTune.h +2 -2
  113. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +45 -13
  114. data/vendor/faiss/faiss/gpu/GpuCloner.h +2 -2
  115. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +12 -6
  116. data/vendor/faiss/faiss/gpu/GpuDistance.h +11 -7
  117. data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +3 -3
  118. data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +2 -2
  119. data/vendor/faiss/faiss/gpu/GpuIndex.h +10 -15
  120. data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +2 -2
  121. data/vendor/faiss/faiss/gpu/GpuIndexCagra.h +285 -0
  122. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +2 -2
  123. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +8 -2
  124. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +4 -2
  125. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +3 -3
  126. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +2 -2
  127. data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +2 -2
  128. data/vendor/faiss/faiss/gpu/GpuResources.cpp +7 -2
  129. data/vendor/faiss/faiss/gpu/GpuResources.h +11 -4
  130. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +66 -11
  131. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +15 -5
  132. data/vendor/faiss/faiss/gpu/impl/IndexUtils.h +2 -2
  133. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +28 -23
  134. data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +2 -2
  135. data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +2 -2
  136. data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +2 -2
  137. data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +2 -2
  138. data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +2 -2
  139. data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +8 -2
  140. data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +2 -3
  141. data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +2 -2
  142. data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +10 -7
  143. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +2 -2
  144. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +54 -54
  145. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +144 -77
  146. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +51 -51
  147. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +2 -2
  148. data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +3 -3
  149. data/vendor/faiss/faiss/gpu/test/TestGpuResidualQuantizer.cpp +70 -0
  150. data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +74 -4
  151. data/vendor/faiss/faiss/gpu/test/TestUtils.h +2 -2
  152. data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +3 -3
  153. data/vendor/faiss/faiss/gpu/utils/{RaftUtils.h → CuvsUtils.h} +12 -11
  154. data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +8 -2
  155. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +2 -2
  156. data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +2 -2
  157. data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +2 -2
  158. data/vendor/faiss/faiss/gpu/utils/Timer.cpp +6 -3
  159. data/vendor/faiss/faiss/gpu/utils/Timer.h +3 -3
  160. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +79 -11
  161. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +17 -5
  162. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +27 -2
  163. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +11 -3
  164. data/vendor/faiss/faiss/impl/CodePacker.cpp +2 -2
  165. data/vendor/faiss/faiss/impl/CodePacker.h +2 -2
  166. data/vendor/faiss/faiss/impl/DistanceComputer.h +48 -2
  167. data/vendor/faiss/faiss/impl/FaissAssert.h +6 -4
  168. data/vendor/faiss/faiss/impl/FaissException.cpp +2 -2
  169. data/vendor/faiss/faiss/impl/FaissException.h +2 -3
  170. data/vendor/faiss/faiss/impl/HNSW.cpp +378 -205
  171. data/vendor/faiss/faiss/impl/HNSW.h +55 -24
  172. data/vendor/faiss/faiss/impl/IDSelector.cpp +2 -2
  173. data/vendor/faiss/faiss/impl/IDSelector.h +2 -2
  174. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +10 -10
  175. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +2 -2
  176. data/vendor/faiss/faiss/impl/LookupTableScaler.h +36 -2
  177. data/vendor/faiss/faiss/impl/NNDescent.cpp +15 -10
  178. data/vendor/faiss/faiss/impl/NNDescent.h +2 -2
  179. data/vendor/faiss/faiss/impl/NSG.cpp +26 -49
  180. data/vendor/faiss/faiss/impl/NSG.h +20 -8
  181. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +2 -2
  182. data/vendor/faiss/faiss/impl/PolysemousTraining.h +2 -2
  183. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.cpp +2 -4
  184. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +2 -2
  185. data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +2 -2
  186. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +3 -2
  187. data/vendor/faiss/faiss/impl/ProductQuantizer.h +7 -3
  188. data/vendor/faiss/faiss/impl/Quantizer.h +2 -2
  189. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +2 -36
  190. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +3 -13
  191. data/vendor/faiss/faiss/impl/ResultHandler.h +153 -34
  192. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +721 -104
  193. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +5 -2
  194. data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +2 -2
  195. data/vendor/faiss/faiss/impl/ThreadedIndex.h +2 -2
  196. data/vendor/faiss/faiss/impl/code_distance/code_distance-avx2.h +7 -2
  197. data/vendor/faiss/faiss/impl/code_distance/code_distance-avx512.h +248 -0
  198. data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +2 -2
  199. data/vendor/faiss/faiss/impl/code_distance/code_distance-sve.h +440 -0
  200. data/vendor/faiss/faiss/impl/code_distance/code_distance.h +55 -2
  201. data/vendor/faiss/faiss/impl/index_read.cpp +31 -20
  202. data/vendor/faiss/faiss/impl/index_read_utils.h +37 -0
  203. data/vendor/faiss/faiss/impl/index_write.cpp +30 -16
  204. data/vendor/faiss/faiss/impl/io.cpp +15 -7
  205. data/vendor/faiss/faiss/impl/io.h +6 -6
  206. data/vendor/faiss/faiss/impl/io_macros.h +8 -9
  207. data/vendor/faiss/faiss/impl/kmeans1d.cpp +2 -3
  208. data/vendor/faiss/faiss/impl/kmeans1d.h +2 -2
  209. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +2 -3
  210. data/vendor/faiss/faiss/impl/lattice_Zn.h +2 -2
  211. data/vendor/faiss/faiss/impl/platform_macros.h +34 -2
  212. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +13 -2
  213. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +20 -2
  214. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +3 -3
  215. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +450 -3
  216. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +8 -8
  217. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +3 -3
  218. data/vendor/faiss/faiss/impl/simd_result_handlers.h +151 -67
  219. data/vendor/faiss/faiss/index_factory.cpp +51 -34
  220. data/vendor/faiss/faiss/index_factory.h +2 -2
  221. data/vendor/faiss/faiss/index_io.h +14 -7
  222. data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +30 -10
  223. data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +5 -2
  224. data/vendor/faiss/faiss/invlists/DirectMap.cpp +11 -3
  225. data/vendor/faiss/faiss/invlists/DirectMap.h +2 -2
  226. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +57 -19
  227. data/vendor/faiss/faiss/invlists/InvertedLists.h +20 -11
  228. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +2 -2
  229. data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +2 -2
  230. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +23 -9
  231. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +4 -3
  232. data/vendor/faiss/faiss/python/python_callbacks.cpp +5 -5
  233. data/vendor/faiss/faiss/python/python_callbacks.h +2 -2
  234. data/vendor/faiss/faiss/utils/AlignedTable.h +5 -3
  235. data/vendor/faiss/faiss/utils/Heap.cpp +2 -2
  236. data/vendor/faiss/faiss/utils/Heap.h +107 -2
  237. data/vendor/faiss/faiss/utils/NeuralNet.cpp +346 -0
  238. data/vendor/faiss/faiss/utils/NeuralNet.h +147 -0
  239. data/vendor/faiss/faiss/utils/WorkerThread.cpp +2 -2
  240. data/vendor/faiss/faiss/utils/WorkerThread.h +2 -2
  241. data/vendor/faiss/faiss/utils/approx_topk/approx_topk.h +2 -2
  242. data/vendor/faiss/faiss/utils/approx_topk/avx2-inl.h +2 -2
  243. data/vendor/faiss/faiss/utils/approx_topk/generic.h +2 -2
  244. data/vendor/faiss/faiss/utils/approx_topk/mode.h +2 -2
  245. data/vendor/faiss/faiss/utils/approx_topk_hamming/approx_topk_hamming.h +2 -2
  246. data/vendor/faiss/faiss/utils/bf16.h +36 -0
  247. data/vendor/faiss/faiss/utils/distances.cpp +249 -90
  248. data/vendor/faiss/faiss/utils/distances.h +8 -8
  249. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +2 -2
  250. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +2 -2
  251. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +2 -2
  252. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +2 -2
  253. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +2 -2
  254. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.h +2 -2
  255. data/vendor/faiss/faiss/utils/distances_simd.cpp +1543 -56
  256. data/vendor/faiss/faiss/utils/extra_distances-inl.h +72 -2
  257. data/vendor/faiss/faiss/utils/extra_distances.cpp +87 -140
  258. data/vendor/faiss/faiss/utils/extra_distances.h +5 -4
  259. data/vendor/faiss/faiss/utils/fp16-arm.h +2 -2
  260. data/vendor/faiss/faiss/utils/fp16-fp16c.h +2 -2
  261. data/vendor/faiss/faiss/utils/fp16-inl.h +2 -2
  262. data/vendor/faiss/faiss/utils/fp16.h +2 -2
  263. data/vendor/faiss/faiss/utils/hamming-inl.h +2 -2
  264. data/vendor/faiss/faiss/utils/hamming.cpp +3 -4
  265. data/vendor/faiss/faiss/utils/hamming.h +2 -2
  266. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +2 -2
  267. data/vendor/faiss/faiss/utils/hamming_distance/avx512-inl.h +490 -0
  268. data/vendor/faiss/faiss/utils/hamming_distance/common.h +2 -2
  269. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +6 -3
  270. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +7 -3
  271. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +5 -5
  272. data/vendor/faiss/faiss/utils/ordered_key_value.h +2 -2
  273. data/vendor/faiss/faiss/utils/partitioning.cpp +2 -2
  274. data/vendor/faiss/faiss/utils/partitioning.h +2 -2
  275. data/vendor/faiss/faiss/utils/prefetch.h +2 -2
  276. data/vendor/faiss/faiss/utils/quantize_lut.cpp +2 -2
  277. data/vendor/faiss/faiss/utils/quantize_lut.h +2 -2
  278. data/vendor/faiss/faiss/utils/random.cpp +45 -2
  279. data/vendor/faiss/faiss/utils/random.h +27 -2
  280. data/vendor/faiss/faiss/utils/simdlib.h +12 -3
  281. data/vendor/faiss/faiss/utils/simdlib_avx2.h +2 -2
  282. data/vendor/faiss/faiss/utils/simdlib_avx512.h +296 -0
  283. data/vendor/faiss/faiss/utils/simdlib_emulated.h +2 -2
  284. data/vendor/faiss/faiss/utils/simdlib_neon.h +7 -4
  285. data/vendor/faiss/faiss/utils/simdlib_ppc64.h +1084 -0
  286. data/vendor/faiss/faiss/utils/sorting.cpp +2 -2
  287. data/vendor/faiss/faiss/utils/sorting.h +2 -2
  288. data/vendor/faiss/faiss/utils/transpose/transpose-avx2-inl.h +2 -2
  289. data/vendor/faiss/faiss/utils/transpose/transpose-avx512-inl.h +176 -0
  290. data/vendor/faiss/faiss/utils/utils.cpp +17 -10
  291. data/vendor/faiss/faiss/utils/utils.h +7 -3
  292. metadata +22 -11
  293. data/vendor/faiss/faiss/impl/code_distance/code_distance_avx512.h +0 -102
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -15,6 +15,7 @@
15
15
  namespace faiss {
16
16
 
17
17
  struct CodePacker;
18
+ struct IDSelector;
18
19
 
19
20
  /** Inverted Lists that are organized by blocks.
20
21
  *
@@ -47,6 +48,8 @@ struct BlockInvertedLists : InvertedLists {
47
48
  size_t list_size(size_t list_no) const override;
48
49
  const uint8_t* get_codes(size_t list_no) const override;
49
50
  const idx_t* get_ids(size_t list_no) const override;
51
+ /// remove ids from the InvertedLists
52
+ size_t remove_ids(const IDSelector& sel);
50
53
 
51
54
  // works only on empty BlockInvertedLists
52
55
  // the codes should be of size ceil(n_entry / n_per_block) * block_size
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -15,6 +15,7 @@
15
15
  #include <faiss/impl/AuxIndexStructures.h>
16
16
  #include <faiss/impl/FaissAssert.h>
17
17
  #include <faiss/impl/IDSelector.h>
18
+ #include <faiss/invlists/BlockInvertedLists.h>
18
19
 
19
20
  namespace faiss {
20
21
 
@@ -148,8 +149,12 @@ size_t DirectMap::remove_ids(const IDSelector& sel, InvertedLists* invlists) {
148
149
  std::vector<idx_t> toremove(nlist);
149
150
 
150
151
  size_t nremove = 0;
151
-
152
+ BlockInvertedLists* block_invlists =
153
+ dynamic_cast<BlockInvertedLists*>(invlists);
152
154
  if (type == NoMap) {
155
+ if (block_invlists != nullptr) {
156
+ return block_invlists->remove_ids(sel);
157
+ }
153
158
  // exhaustive scan of IVF
154
159
  #pragma omp parallel for
155
160
  for (idx_t i = 0; i < nlist; i++) {
@@ -178,6 +183,9 @@ size_t DirectMap::remove_ids(const IDSelector& sel, InvertedLists* invlists) {
178
183
  }
179
184
  }
180
185
  } else if (type == Hashtable) {
186
+ FAISS_THROW_IF_MSG(
187
+ block_invlists,
188
+ "remove with hashtable is not supported with BlockInvertedLists");
181
189
  const IDSelectorArray* sela =
182
190
  dynamic_cast<const IDSelectorArray*>(&sel);
183
191
  FAISS_THROW_IF_NOT_MSG(
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -1,12 +1,10 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- // -*- c++ -*-
9
-
10
8
  #include <faiss/invlists/InvertedLists.h>
11
9
 
12
10
  #include <cstdio>
@@ -24,18 +22,10 @@ InvertedListsIterator::~InvertedListsIterator() {}
24
22
  ******************************************/
25
23
 
26
24
  InvertedLists::InvertedLists(size_t nlist, size_t code_size)
27
- : nlist(nlist), code_size(code_size), use_iterator(false) {}
25
+ : nlist(nlist), code_size(code_size) {}
28
26
 
29
27
  InvertedLists::~InvertedLists() {}
30
28
 
31
- bool InvertedLists::is_empty(size_t list_no, void* inverted_list_context)
32
- const {
33
- return use_iterator ? !std::unique_ptr<InvertedListsIterator>(
34
- get_iterator(list_no, inverted_list_context))
35
- ->is_available()
36
- : list_size(list_no) == 0;
37
- }
38
-
39
29
  idx_t InvertedLists::get_single_id(size_t list_no, size_t offset) const {
40
30
  assert(offset < list_size(list_no));
41
31
  const idx_t* ids = get_ids(list_no);
@@ -78,12 +68,6 @@ void InvertedLists::reset() {
78
68
  }
79
69
  }
80
70
 
81
- InvertedListsIterator* InvertedLists::get_iterator(
82
- size_t /*list_no*/,
83
- void* /*inverted_list_context*/) const {
84
- FAISS_THROW_MSG("get_iterator is not supported");
85
- }
86
-
87
71
  void InvertedLists::merge_from(InvertedLists* oivf, size_t add_id) {
88
72
  #pragma omp parallel for
89
73
  for (idx_t i = 0; i < nlist; i++) {
@@ -233,6 +217,54 @@ size_t InvertedLists::compute_ntotal() const {
233
217
  return tot;
234
218
  }
235
219
 
220
+ bool InvertedLists::is_empty(size_t list_no, void* inverted_list_context)
221
+ const {
222
+ if (use_iterator) {
223
+ return !std::unique_ptr<InvertedListsIterator>(
224
+ get_iterator(list_no, inverted_list_context))
225
+ ->is_available();
226
+ } else {
227
+ FAISS_THROW_IF_NOT(inverted_list_context == nullptr);
228
+ return list_size(list_no) == 0;
229
+ }
230
+ }
231
+
232
+ // implemnent iterator on top of get_codes / get_ids
233
+ namespace {
234
+
235
+ struct CodeArrayIterator : InvertedListsIterator {
236
+ size_t list_size;
237
+ size_t code_size;
238
+ InvertedLists::ScopedCodes codes;
239
+ InvertedLists::ScopedIds ids;
240
+ size_t idx = 0;
241
+
242
+ CodeArrayIterator(const InvertedLists* il, size_t list_no)
243
+ : list_size(il->list_size(list_no)),
244
+ code_size(il->code_size),
245
+ codes(il, list_no),
246
+ ids(il, list_no) {}
247
+
248
+ bool is_available() const override {
249
+ return idx < list_size;
250
+ }
251
+ void next() override {
252
+ idx++;
253
+ }
254
+ std::pair<idx_t, const uint8_t*> get_id_and_codes() override {
255
+ return {ids[idx], codes.get() + code_size * idx};
256
+ }
257
+ };
258
+
259
+ } // namespace
260
+
261
+ InvertedListsIterator* InvertedLists::get_iterator(
262
+ size_t list_no,
263
+ void* inverted_list_context) const {
264
+ FAISS_THROW_IF_NOT(inverted_list_context == nullptr);
265
+ return new CodeArrayIterator(this, list_no);
266
+ }
267
+
236
268
  /*****************************************
237
269
  * ArrayInvertedLists implementation
238
270
  ******************************************/
@@ -264,6 +296,12 @@ size_t ArrayInvertedLists::list_size(size_t list_no) const {
264
296
  return ids[list_no].size();
265
297
  }
266
298
 
299
+ bool ArrayInvertedLists::is_empty(size_t list_no, void* inverted_list_context)
300
+ const {
301
+ FAISS_THROW_IF_NOT(inverted_list_context == nullptr);
302
+ return ids[list_no].size() == 0;
303
+ }
304
+
267
305
  const uint8_t* ArrayInvertedLists::get_codes(size_t list_no) const {
268
306
  assert(list_no < nlist);
269
307
  return codes[list_no].data();
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -37,7 +37,9 @@ struct InvertedListsIterator {
37
37
  struct InvertedLists {
38
38
  size_t nlist; ///< number of possible key values
39
39
  size_t code_size; ///< code size per vector in bytes
40
- bool use_iterator;
40
+
41
+ /// request to use iterator rather than get_codes / get_ids
42
+ bool use_iterator = false;
41
43
 
42
44
  InvertedLists(size_t nlist, size_t code_size);
43
45
 
@@ -50,17 +52,9 @@ struct InvertedLists {
50
52
  /*************************
51
53
  * Read only functions */
52
54
 
53
- // check if the list is empty
54
- bool is_empty(size_t list_no, void* inverted_list_context) const;
55
-
56
55
  /// get the size of a list
57
56
  virtual size_t list_size(size_t list_no) const = 0;
58
57
 
59
- /// get iterable for lists that use_iterator
60
- virtual InvertedListsIterator* get_iterator(
61
- size_t list_no,
62
- void* inverted_list_context) const;
63
-
64
58
  /** get the codes for an inverted list
65
59
  * must be released by release_codes
66
60
  *
@@ -92,6 +86,18 @@ struct InvertedLists {
92
86
  /// a list can be -1 hence the signed long
93
87
  virtual void prefetch_lists(const idx_t* list_nos, int nlist) const;
94
88
 
89
+ /*****************************************
90
+ * Iterator interface (with context) */
91
+
92
+ /// check if the list is empty
93
+ virtual bool is_empty(size_t list_no, void* inverted_list_context = nullptr)
94
+ const;
95
+
96
+ /// get iterable for lists that use_iterator
97
+ virtual InvertedListsIterator* get_iterator(
98
+ size_t list_no,
99
+ void* inverted_list_context = nullptr) const;
100
+
95
101
  /*************************
96
102
  * writing functions */
97
103
 
@@ -262,6 +268,9 @@ struct ArrayInvertedLists : InvertedLists {
262
268
  /// permute the inverted lists, map maps new_id to old_id
263
269
  void permute_invlists(const idx_t* map);
264
270
 
271
+ bool is_empty(size_t list_no, void* inverted_list_context = nullptr)
272
+ const override;
273
+
265
274
  ~ArrayInvertedLists() override;
266
275
  };
267
276
 
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -15,7 +15,6 @@
15
15
 
16
16
  #include <sys/mman.h>
17
17
  #include <sys/stat.h>
18
- #include <sys/types.h>
19
18
  #include <unistd.h>
20
19
 
21
20
  #include <faiss/impl/FaissAssert.h>
@@ -394,8 +393,8 @@ const idx_t* OnDiskInvertedLists::get_ids(size_t list_no) const {
394
393
  return nullptr;
395
394
  }
396
395
 
397
- return (
398
- const idx_t*)(ptr + lists[list_no].offset + code_size * lists[list_no].capacity);
396
+ return (const idx_t*)(ptr + lists[list_no].offset +
397
+ code_size * lists[list_no].capacity);
399
398
  }
400
399
 
401
400
  void OnDiskInvertedLists::update_entries(
@@ -565,15 +564,16 @@ void OnDiskInvertedLists::free_slot(size_t offset, size_t capacity) {
565
564
  /*****************************************
566
565
  * Compact form
567
566
  *****************************************/
568
-
569
- size_t OnDiskInvertedLists::merge_from(
567
+ size_t OnDiskInvertedLists::merge_from_multiple(
570
568
  const InvertedLists** ils,
571
569
  int n_il,
570
+ bool shift_ids,
572
571
  bool verbose) {
573
572
  FAISS_THROW_IF_NOT_MSG(
574
573
  totsize == 0, "works only on an empty InvertedLists");
575
574
 
576
575
  std::vector<size_t> sizes(nlist);
576
+ std::vector<size_t> shift_id_offsets(n_il);
577
577
  for (int i = 0; i < n_il; i++) {
578
578
  const InvertedLists* il = ils[i];
579
579
  FAISS_THROW_IF_NOT(il->nlist == nlist && il->code_size == code_size);
@@ -581,6 +581,10 @@ size_t OnDiskInvertedLists::merge_from(
581
581
  for (size_t j = 0; j < nlist; j++) {
582
582
  sizes[j] += il->list_size(j);
583
583
  }
584
+
585
+ size_t il_totsize = il->compute_ntotal();
586
+ shift_id_offsets[i] =
587
+ (shift_ids && i > 0) ? shift_id_offsets[i - 1] + il_totsize : 0;
584
588
  }
585
589
 
586
590
  size_t cums = 0;
@@ -605,11 +609,21 @@ size_t OnDiskInvertedLists::merge_from(
605
609
  const InvertedLists* il = ils[i];
606
610
  size_t n_entry = il->list_size(j);
607
611
  l.size += n_entry;
612
+ ScopedIds scope_ids(il, j);
613
+ const idx_t* scope_ids_data = scope_ids.get();
614
+ std::vector<idx_t> new_ids;
615
+ if (shift_ids) {
616
+ new_ids.resize(n_entry);
617
+ for (size_t k = 0; k < n_entry; k++) {
618
+ new_ids[k] = scope_ids[k] + shift_id_offsets[i];
619
+ }
620
+ scope_ids_data = new_ids.data();
621
+ }
608
622
  update_entries(
609
623
  j,
610
624
  l.size - n_entry,
611
625
  n_entry,
612
- ScopedIds(il, j).get(),
626
+ scope_ids_data,
613
627
  ScopedCodes(il, j).get());
614
628
  }
615
629
  assert(l.size == l.capacity);
@@ -638,7 +652,7 @@ size_t OnDiskInvertedLists::merge_from(
638
652
  size_t OnDiskInvertedLists::merge_from_1(
639
653
  const InvertedLists* ils,
640
654
  bool verbose) {
641
- return merge_from(&ils, 1, verbose);
655
+ return merge_from_multiple(&ils, 1, verbose);
642
656
  }
643
657
 
644
658
  void OnDiskInvertedLists::crop_invlists(size_t l0, size_t l1) {
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -101,9 +101,10 @@ struct OnDiskInvertedLists : InvertedLists {
101
101
 
102
102
  // copy all inverted lists into *this, in compact form (without
103
103
  // allocating slots)
104
- size_t merge_from(
104
+ size_t merge_from_multiple(
105
105
  const InvertedLists** ils,
106
106
  int n_il,
107
+ bool shift_ids = false,
107
108
  bool verbose = false);
108
109
 
109
110
  /// same as merge_from for a single invlist
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -46,7 +46,7 @@ size_t PyCallbackIOWriter::operator()(
46
46
  size_t wi = ws > bs ? bs : ws;
47
47
  PyObject* result = PyObject_CallFunction(
48
48
  callback, "(N)", PyBytes_FromStringAndSize(ptr, wi));
49
- if (result == NULL) {
49
+ if (result == nullptr) {
50
50
  FAISS_THROW_MSG("py err");
51
51
  }
52
52
  // TODO check nb of bytes written
@@ -77,7 +77,7 @@ size_t PyCallbackIOReader::operator()(void* ptrv, size_t size, size_t nitems) {
77
77
  while (rs > 0) {
78
78
  size_t ri = rs > bs ? bs : rs;
79
79
  PyObject* result = PyObject_CallFunction(callback, "(n)", ri);
80
- if (result == NULL) {
80
+ if (result == nullptr) {
81
81
  FAISS_THROW_MSG("propagate py error");
82
82
  }
83
83
  if (!PyBytes_Check(result)) {
@@ -122,7 +122,7 @@ bool PyCallbackIDSelector::is_member(faiss::idx_t id) const {
122
122
  FAISS_THROW_IF_NOT((id >> 32) == 0);
123
123
  PyThreadLock gil;
124
124
  PyObject* result = PyObject_CallFunction(callback, "(n)", int(id));
125
- if (result == NULL) {
125
+ if (result == nullptr) {
126
126
  FAISS_THROW_MSG("propagate py error");
127
127
  }
128
128
  bool b = PyObject_IsTrue(result);
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -63,7 +63,9 @@ struct AlignedTableTightAlloc {
63
63
  }
64
64
 
65
65
  void clear() {
66
- memset(ptr, 0, nbytes());
66
+ if (numel > 0) {
67
+ memset(ptr, 0, nbytes());
68
+ }
67
69
  }
68
70
  size_t size() const {
69
71
  return numel;
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -1,5 +1,5 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -30,6 +30,7 @@
30
30
  #include <cstdio>
31
31
 
32
32
  #include <limits>
33
+ #include <utility>
33
34
 
34
35
  #include <faiss/utils/ordered_key_value.h>
35
36
 
@@ -200,6 +201,110 @@ inline void maxheap_replace_top(
200
201
  heap_replace_top<CMax<T, int64_t>>(k, bh_val, bh_ids, val, ids);
201
202
  }
202
203
 
204
+ /*******************************************************************
205
+ * Basic heap<std:pair<>> ops: push and pop
206
+ *******************************************************************/
207
+
208
+ // This section contains a heap implementation that works with
209
+ // std::pair<Priority, Value> elements.
210
+
211
+ /** Pops the top element from the heap defined by bh_val[0..k-1] and
212
+ * bh_ids[0..k-1]. on output the element at k-1 is undefined.
213
+ */
214
+ template <class C>
215
+ inline void heap_pop(size_t k, std::pair<typename C::T, typename C::TI>* bh) {
216
+ bh--; /* Use 1-based indexing for easier node->child translation */
217
+ typename C::T val = bh[k].first;
218
+ typename C::TI id = bh[k].second;
219
+ size_t i = 1, i1, i2;
220
+ while (1) {
221
+ i1 = i << 1;
222
+ i2 = i1 + 1;
223
+ if (i1 > k)
224
+ break;
225
+ if ((i2 == k + 1) ||
226
+ C::cmp2(bh[i1].first, bh[i2].first, bh[i1].second, bh[i2].second)) {
227
+ if (C::cmp2(val, bh[i1].first, id, bh[i1].second)) {
228
+ break;
229
+ }
230
+ bh[i] = bh[i1];
231
+ i = i1;
232
+ } else {
233
+ if (C::cmp2(val, bh[i2].first, id, bh[i2].second)) {
234
+ break;
235
+ }
236
+ bh[i] = bh[i2];
237
+ i = i2;
238
+ }
239
+ }
240
+ bh[i] = bh[k];
241
+ }
242
+
243
+ /** Pushes the element (val, ids) into the heap bh_val[0..k-2] and
244
+ * bh_ids[0..k-2]. on output the element at k-1 is defined.
245
+ */
246
+ template <class C>
247
+ inline void heap_push(
248
+ size_t k,
249
+ std::pair<typename C::T, typename C::TI>* bh,
250
+ typename C::T val,
251
+ typename C::TI id) {
252
+ bh--; /* Use 1-based indexing for easier node->child translation */
253
+ size_t i = k, i_father;
254
+ while (i > 1) {
255
+ i_father = i >> 1;
256
+ auto bh_v = bh[i_father];
257
+ if (!C::cmp2(val, bh_v.first, id, bh_v.second)) {
258
+ /* the heap structure is ok */
259
+ break;
260
+ }
261
+ bh[i] = bh_v;
262
+ i = i_father;
263
+ }
264
+ bh[i] = std::make_pair(val, id);
265
+ }
266
+
267
+ /**
268
+ * Replaces the top element from the heap defined by bh_val[0..k-1] and
269
+ * bh_ids[0..k-1], and for identical bh_val[] values also sorts by bh_ids[]
270
+ * values.
271
+ */
272
+ template <class C>
273
+ inline void heap_replace_top(
274
+ size_t k,
275
+ std::pair<typename C::T, typename C::TI>* bh,
276
+ typename C::T val,
277
+ typename C::TI id) {
278
+ bh--; /* Use 1-based indexing for easier node->child translation */
279
+ size_t i = 1, i1, i2;
280
+ while (1) {
281
+ i1 = i << 1;
282
+ i2 = i1 + 1;
283
+ if (i1 > k) {
284
+ break;
285
+ }
286
+
287
+ // Note that C::cmp2() is a bool function answering
288
+ // `(a1 > b1) || ((a1 == b1) && (a2 > b2))` for max
289
+ // heap and same with the `<` sign for min heap.
290
+ if ((i2 == k + 1) ||
291
+ C::cmp2(bh[i1].first, bh[i2].first, bh[i1].second, bh[i2].second)) {
292
+ if (C::cmp2(val, bh[i1].first, id, bh[i1].second)) {
293
+ break;
294
+ }
295
+ bh[i] = bh[i1];
296
+ i = i1;
297
+ } else {
298
+ if (C::cmp2(val, bh[i2].first, id, bh[i2].second)) {
299
+ break;
300
+ }
301
+ bh[i] = bh[i2];
302
+ i = i2;
303
+ }
304
+ }
305
+ bh[i] = std::make_pair(val, id);
306
+ }
307
+
203
308
  /*******************************************************************
204
309
  * Heap initialization
205
310
  *******************************************************************/