faiss 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1 -1
  5. data/ext/faiss/extconf.rb +9 -2
  6. data/ext/faiss/index.cpp +1 -1
  7. data/ext/faiss/index_binary.cpp +2 -2
  8. data/ext/faiss/product_quantizer.cpp +1 -1
  9. data/lib/faiss/version.rb +1 -1
  10. data/vendor/faiss/faiss/AutoTune.cpp +7 -7
  11. data/vendor/faiss/faiss/AutoTune.h +0 -1
  12. data/vendor/faiss/faiss/Clustering.cpp +4 -18
  13. data/vendor/faiss/faiss/Clustering.h +31 -21
  14. data/vendor/faiss/faiss/IVFlib.cpp +22 -11
  15. data/vendor/faiss/faiss/Index.cpp +1 -1
  16. data/vendor/faiss/faiss/Index.h +20 -5
  17. data/vendor/faiss/faiss/Index2Layer.cpp +7 -7
  18. data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +176 -166
  19. data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +15 -15
  20. data/vendor/faiss/faiss/IndexBinary.cpp +9 -4
  21. data/vendor/faiss/faiss/IndexBinary.h +8 -19
  22. data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +2 -1
  23. data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +24 -31
  24. data/vendor/faiss/faiss/IndexBinaryHash.cpp +25 -50
  25. data/vendor/faiss/faiss/IndexBinaryIVF.cpp +106 -187
  26. data/vendor/faiss/faiss/IndexFastScan.cpp +90 -159
  27. data/vendor/faiss/faiss/IndexFastScan.h +9 -8
  28. data/vendor/faiss/faiss/IndexFlat.cpp +195 -3
  29. data/vendor/faiss/faiss/IndexFlat.h +20 -1
  30. data/vendor/faiss/faiss/IndexFlatCodes.cpp +11 -0
  31. data/vendor/faiss/faiss/IndexFlatCodes.h +3 -1
  32. data/vendor/faiss/faiss/IndexHNSW.cpp +112 -316
  33. data/vendor/faiss/faiss/IndexHNSW.h +12 -48
  34. data/vendor/faiss/faiss/IndexIDMap.cpp +69 -28
  35. data/vendor/faiss/faiss/IndexIDMap.h +24 -2
  36. data/vendor/faiss/faiss/IndexIVF.cpp +159 -53
  37. data/vendor/faiss/faiss/IndexIVF.h +37 -5
  38. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +18 -26
  39. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +3 -2
  40. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +19 -46
  41. data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -3
  42. data/vendor/faiss/faiss/IndexIVFFastScan.cpp +433 -405
  43. data/vendor/faiss/faiss/IndexIVFFastScan.h +56 -26
  44. data/vendor/faiss/faiss/IndexIVFFlat.cpp +15 -5
  45. data/vendor/faiss/faiss/IndexIVFFlat.h +3 -2
  46. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +172 -0
  47. data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.h +56 -0
  48. data/vendor/faiss/faiss/IndexIVFPQ.cpp +78 -122
  49. data/vendor/faiss/faiss/IndexIVFPQ.h +6 -7
  50. data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +18 -50
  51. data/vendor/faiss/faiss/IndexIVFPQFastScan.h +4 -3
  52. data/vendor/faiss/faiss/IndexIVFPQR.cpp +45 -29
  53. data/vendor/faiss/faiss/IndexIVFPQR.h +5 -2
  54. data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +25 -27
  55. data/vendor/faiss/faiss/IndexIVFSpectralHash.h +6 -6
  56. data/vendor/faiss/faiss/IndexLSH.cpp +14 -16
  57. data/vendor/faiss/faiss/IndexNNDescent.cpp +3 -4
  58. data/vendor/faiss/faiss/IndexNSG.cpp +11 -27
  59. data/vendor/faiss/faiss/IndexNSG.h +10 -10
  60. data/vendor/faiss/faiss/IndexPQ.cpp +72 -88
  61. data/vendor/faiss/faiss/IndexPQ.h +1 -4
  62. data/vendor/faiss/faiss/IndexPQFastScan.cpp +1 -1
  63. data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -31
  64. data/vendor/faiss/faiss/IndexRefine.cpp +49 -19
  65. data/vendor/faiss/faiss/IndexRefine.h +7 -0
  66. data/vendor/faiss/faiss/IndexReplicas.cpp +23 -26
  67. data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +22 -16
  68. data/vendor/faiss/faiss/IndexScalarQuantizer.h +6 -4
  69. data/vendor/faiss/faiss/IndexShards.cpp +21 -29
  70. data/vendor/faiss/faiss/IndexShardsIVF.cpp +1 -2
  71. data/vendor/faiss/faiss/MatrixStats.cpp +17 -32
  72. data/vendor/faiss/faiss/MatrixStats.h +21 -9
  73. data/vendor/faiss/faiss/MetaIndexes.cpp +35 -35
  74. data/vendor/faiss/faiss/VectorTransform.cpp +13 -26
  75. data/vendor/faiss/faiss/VectorTransform.h +7 -7
  76. data/vendor/faiss/faiss/clone_index.cpp +15 -10
  77. data/vendor/faiss/faiss/clone_index.h +3 -0
  78. data/vendor/faiss/faiss/gpu/GpuCloner.cpp +87 -4
  79. data/vendor/faiss/faiss/gpu/GpuCloner.h +22 -0
  80. data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +7 -0
  81. data/vendor/faiss/faiss/gpu/GpuDistance.h +46 -38
  82. data/vendor/faiss/faiss/gpu/GpuIndex.h +28 -4
  83. data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +4 -4
  84. data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +8 -9
  85. data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +18 -3
  86. data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -11
  87. data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +1 -3
  88. data/vendor/faiss/faiss/gpu/GpuResources.cpp +24 -3
  89. data/vendor/faiss/faiss/gpu/GpuResources.h +39 -11
  90. data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +117 -17
  91. data/vendor/faiss/faiss/gpu/StandardGpuResources.h +57 -3
  92. data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +1 -1
  93. data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +25 -0
  94. data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +129 -9
  95. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +267 -40
  96. data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +299 -208
  97. data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +1 -0
  98. data/vendor/faiss/faiss/gpu/utils/RaftUtils.h +75 -0
  99. data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +3 -1
  100. data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +5 -5
  101. data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +1 -1
  102. data/vendor/faiss/faiss/impl/AuxIndexStructures.h +1 -2
  103. data/vendor/faiss/faiss/impl/DistanceComputer.h +24 -1
  104. data/vendor/faiss/faiss/impl/FaissException.h +13 -34
  105. data/vendor/faiss/faiss/impl/HNSW.cpp +321 -70
  106. data/vendor/faiss/faiss/impl/HNSW.h +9 -8
  107. data/vendor/faiss/faiss/impl/IDSelector.h +4 -4
  108. data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +3 -1
  109. data/vendor/faiss/faiss/impl/NNDescent.cpp +29 -19
  110. data/vendor/faiss/faiss/impl/NSG.h +1 -1
  111. data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +14 -12
  112. data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +1 -1
  113. data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +24 -22
  114. data/vendor/faiss/faiss/impl/ProductQuantizer.h +1 -1
  115. data/vendor/faiss/faiss/impl/Quantizer.h +1 -1
  116. data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +27 -1015
  117. data/vendor/faiss/faiss/impl/ResidualQuantizer.h +5 -63
  118. data/vendor/faiss/faiss/impl/ResultHandler.h +232 -176
  119. data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +444 -104
  120. data/vendor/faiss/faiss/impl/ScalarQuantizer.h +0 -8
  121. data/vendor/faiss/faiss/impl/code_distance/code_distance-avx2.h +280 -42
  122. data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +21 -14
  123. data/vendor/faiss/faiss/impl/code_distance/code_distance.h +22 -12
  124. data/vendor/faiss/faiss/impl/index_read.cpp +45 -19
  125. data/vendor/faiss/faiss/impl/index_write.cpp +60 -41
  126. data/vendor/faiss/faiss/impl/io.cpp +10 -10
  127. data/vendor/faiss/faiss/impl/lattice_Zn.cpp +1 -1
  128. data/vendor/faiss/faiss/impl/platform_macros.h +18 -1
  129. data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +3 -0
  130. data/vendor/faiss/faiss/impl/pq4_fast_scan.h +7 -6
  131. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +52 -38
  132. data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +40 -49
  133. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +960 -0
  134. data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +176 -0
  135. data/vendor/faiss/faiss/impl/simd_result_handlers.h +374 -202
  136. data/vendor/faiss/faiss/index_factory.cpp +10 -7
  137. data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
  138. data/vendor/faiss/faiss/invlists/InvertedLists.cpp +27 -9
  139. data/vendor/faiss/faiss/invlists/InvertedLists.h +12 -3
  140. data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +3 -3
  141. data/vendor/faiss/faiss/python/python_callbacks.cpp +1 -1
  142. data/vendor/faiss/faiss/utils/Heap.cpp +3 -1
  143. data/vendor/faiss/faiss/utils/WorkerThread.h +1 -0
  144. data/vendor/faiss/faiss/utils/distances.cpp +128 -74
  145. data/vendor/faiss/faiss/utils/distances.h +81 -4
  146. data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +5 -5
  147. data/vendor/faiss/faiss/utils/distances_fused/avx512.h +2 -2
  148. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +2 -2
  149. data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +1 -1
  150. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +5 -5
  151. data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.h +1 -1
  152. data/vendor/faiss/faiss/utils/distances_simd.cpp +428 -70
  153. data/vendor/faiss/faiss/utils/fp16-arm.h +29 -0
  154. data/vendor/faiss/faiss/utils/fp16.h +2 -0
  155. data/vendor/faiss/faiss/utils/hamming.cpp +162 -110
  156. data/vendor/faiss/faiss/utils/hamming.h +58 -0
  157. data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +16 -89
  158. data/vendor/faiss/faiss/utils/hamming_distance/common.h +1 -0
  159. data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +15 -87
  160. data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +57 -0
  161. data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +14 -104
  162. data/vendor/faiss/faiss/utils/partitioning.cpp +3 -4
  163. data/vendor/faiss/faiss/utils/prefetch.h +77 -0
  164. data/vendor/faiss/faiss/utils/quantize_lut.cpp +0 -14
  165. data/vendor/faiss/faiss/utils/simdlib_avx2.h +0 -6
  166. data/vendor/faiss/faiss/utils/simdlib_neon.h +72 -77
  167. data/vendor/faiss/faiss/utils/sorting.cpp +140 -5
  168. data/vendor/faiss/faiss/utils/sorting.h +27 -0
  169. data/vendor/faiss/faiss/utils/utils.cpp +112 -6
  170. data/vendor/faiss/faiss/utils/utils.h +57 -20
  171. metadata +10 -3
@@ -216,7 +216,7 @@ VectorTransform* parse_VectorTransform(const std::string& description, int d) {
216
216
  return new RemapDimensionsTransform(d, std::max(d_out, d), false);
217
217
  }
218
218
  return nullptr;
219
- };
219
+ }
220
220
 
221
221
  /***************************************************************
222
222
  * Parse IndexIVF
@@ -440,11 +440,13 @@ IndexHNSW* parse_IndexHNSW(
440
440
  if (match("Flat|")) {
441
441
  return new IndexHNSWFlat(d, hnsw_M, mt);
442
442
  }
443
- if (match("PQ([0-9]+)(np)?")) {
443
+
444
+ if (match("PQ([0-9]+)(x[0-9]+)?(np)?")) {
444
445
  int M = std::stoi(sm[1].str());
445
- IndexHNSWPQ* ipq = new IndexHNSWPQ(d, M, hnsw_M);
446
+ int nbit = mres_to_int(sm[2], 8, 1);
447
+ IndexHNSWPQ* ipq = new IndexHNSWPQ(d, M, hnsw_M, nbit);
446
448
  dynamic_cast<IndexPQ*>(ipq->storage)->do_polysemous_training =
447
- sm[2].str() != "np";
449
+ sm[3].str() != "np";
448
450
  return ipq;
449
451
  }
450
452
  if (match(sq_pattern)) {
@@ -490,11 +492,12 @@ IndexNSG* parse_IndexNSG(
490
492
  if (match("Flat|")) {
491
493
  return new IndexNSGFlat(d, nsg_R, mt);
492
494
  }
493
- if (match("PQ([0-9]+)(np)?")) {
495
+ if (match("PQ([0-9]+)(x[0-9]+)?(np)?")) {
494
496
  int M = std::stoi(sm[1].str());
495
- IndexNSGPQ* ipq = new IndexNSGPQ(d, M, nsg_R);
497
+ int nbit = mres_to_int(sm[2], 8, 1);
498
+ IndexNSGPQ* ipq = new IndexNSGPQ(d, M, nsg_R, nbit);
496
499
  dynamic_cast<IndexPQ*>(ipq->storage)->do_polysemous_training =
497
- sm[2].str() != "np";
500
+ sm[3].str() != "np";
498
501
  return ipq;
499
502
  }
500
503
  if (match(sq_pattern)) {
@@ -199,7 +199,7 @@ size_t DirectMap::remove_ids(const IDSelector& sel, InvertedLists* invlists) {
199
199
  last_id,
200
200
  ScopedCodes(invlists, list_no, last).get());
201
201
  // update hash entry for last element
202
- hashtable[last_id] = list_no << 32 | offset;
202
+ hashtable[last_id] = lo_build(list_no, offset);
203
203
  }
204
204
  invlists->resize(list_no, last);
205
205
  nremove++;
@@ -28,11 +28,12 @@ InvertedLists::InvertedLists(size_t nlist, size_t code_size)
28
28
 
29
29
  InvertedLists::~InvertedLists() {}
30
30
 
31
- bool InvertedLists::is_empty(size_t list_no) const {
32
- return use_iterator
33
- ? !std::unique_ptr<InvertedListsIterator>(get_iterator(list_no))
34
- ->is_available()
35
- : list_size(list_no) == 0;
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;
36
37
  }
37
38
 
38
39
  idx_t InvertedLists::get_single_id(size_t list_no, size_t offset) const {
@@ -58,7 +59,8 @@ const uint8_t* InvertedLists::get_single_code(size_t list_no, size_t offset)
58
59
  size_t InvertedLists::add_entry(
59
60
  size_t list_no,
60
61
  idx_t theid,
61
- const uint8_t* code) {
62
+ const uint8_t* code,
63
+ void* /*inverted_list_context*/) {
62
64
  return add_entries(list_no, 1, &theid, code);
63
65
  }
64
66
 
@@ -76,7 +78,9 @@ void InvertedLists::reset() {
76
78
  }
77
79
  }
78
80
 
79
- InvertedListsIterator* InvertedLists::get_iterator(size_t /*list_no*/) const {
81
+ InvertedListsIterator* InvertedLists::get_iterator(
82
+ size_t /*list_no*/,
83
+ void* /*inverted_list_context*/) const {
80
84
  FAISS_THROW_MSG("get_iterator is not supported");
81
85
  }
82
86
 
@@ -287,6 +291,20 @@ void ArrayInvertedLists::update_entries(
287
291
  memcpy(&codes[list_no][offset * code_size], codes_in, code_size * n_entry);
288
292
  }
289
293
 
294
+ void ArrayInvertedLists::permute_invlists(const idx_t* map) {
295
+ std::vector<std::vector<uint8_t>> new_codes(nlist);
296
+ std::vector<std::vector<idx_t>> new_ids(nlist);
297
+
298
+ for (size_t i = 0; i < nlist; i++) {
299
+ size_t o = map[i];
300
+ FAISS_THROW_IF_NOT(o < nlist);
301
+ std::swap(new_codes[i], codes[o]);
302
+ std::swap(new_ids[i], ids[o]);
303
+ }
304
+ std::swap(codes, new_codes);
305
+ std::swap(ids, new_ids);
306
+ }
307
+
290
308
  ArrayInvertedLists::~ArrayInvertedLists() {}
291
309
 
292
310
  /*****************************************************************
@@ -423,7 +441,7 @@ idx_t translate_list_no(const SliceInvertedLists* sil, idx_t list_no) {
423
441
  return list_no + sil->i0;
424
442
  }
425
443
 
426
- }; // namespace
444
+ } // namespace
427
445
 
428
446
  SliceInvertedLists::SliceInvertedLists(
429
447
  const InvertedLists* il,
@@ -508,7 +526,7 @@ idx_t sum_il_sizes(int nil, const InvertedLists** ils_in) {
508
526
  return tot;
509
527
  }
510
528
 
511
- }; // namespace
529
+ } // namespace
512
530
 
513
531
  VStackInvertedLists::VStackInvertedLists(int nil, const InvertedLists** ils_in)
514
532
  : ReadOnlyInvertedLists(
@@ -51,13 +51,15 @@ struct InvertedLists {
51
51
  * Read only functions */
52
52
 
53
53
  // check if the list is empty
54
- bool is_empty(size_t list_no) const;
54
+ bool is_empty(size_t list_no, void* inverted_list_context) const;
55
55
 
56
56
  /// get the size of a list
57
57
  virtual size_t list_size(size_t list_no) const = 0;
58
58
 
59
59
  /// get iterable for lists that use_iterator
60
- virtual InvertedListsIterator* get_iterator(size_t list_no) const;
60
+ virtual InvertedListsIterator* get_iterator(
61
+ size_t list_no,
62
+ void* inverted_list_context) const;
61
63
 
62
64
  /** get the codes for an inverted list
63
65
  * must be released by release_codes
@@ -94,7 +96,11 @@ struct InvertedLists {
94
96
  * writing functions */
95
97
 
96
98
  /// add one entry to an inverted list
97
- virtual size_t add_entry(size_t list_no, idx_t theid, const uint8_t* code);
99
+ virtual size_t add_entry(
100
+ size_t list_no,
101
+ idx_t theid,
102
+ const uint8_t* code,
103
+ void* inverted_list_context = nullptr);
98
104
 
99
105
  virtual size_t add_entries(
100
106
  size_t list_no,
@@ -253,6 +259,9 @@ struct ArrayInvertedLists : InvertedLists {
253
259
 
254
260
  void resize(size_t list_no, size_t new_size) override;
255
261
 
262
+ /// permute the inverted lists, map maps new_id to old_id
263
+ void permute_invlists(const idx_t* map);
264
+
256
265
  ~ArrayInvertedLists() override;
257
266
  };
258
267
 
@@ -407,7 +407,7 @@ void OnDiskInvertedLists::update_entries(
407
407
  FAISS_THROW_IF_NOT(!read_only);
408
408
  if (n_entry == 0)
409
409
  return;
410
- const List& l = lists[list_no];
410
+ [[maybe_unused]] const List& l = lists[list_no];
411
411
  assert(n_entry + offset <= l.size);
412
412
  idx_t* ids = const_cast<idx_t*>(get_ids(list_no));
413
413
  memcpy(ids + offset, ids_in, sizeof(ids_in[0]) * n_entry);
@@ -524,7 +524,7 @@ void OnDiskInvertedLists::free_slot(size_t offset, size_t capacity) {
524
524
  it++;
525
525
  }
526
526
 
527
- size_t inf = 1UL << 60;
527
+ size_t inf = ((size_t)1) << 60;
528
528
 
529
529
  size_t end_prev = inf;
530
530
  if (it != slots.begin()) {
@@ -533,7 +533,7 @@ void OnDiskInvertedLists::free_slot(size_t offset, size_t capacity) {
533
533
  end_prev = prev->offset + prev->capacity;
534
534
  }
535
535
 
536
- size_t begin_next = 1L << 60;
536
+ size_t begin_next = ((size_t)1) << 60;
537
537
  if (it != slots.end()) {
538
538
  begin_next = it->offset;
539
539
  }
@@ -22,7 +22,7 @@ struct PyThreadLock {
22
22
  }
23
23
  };
24
24
 
25
- }; // namespace
25
+ } // namespace
26
26
 
27
27
  /***********************************************************
28
28
  * Callbacks for IO reader and writer
@@ -93,7 +93,7 @@ void HeapArray<C>::addn_query_subset_with_ids(
93
93
  }
94
94
  #pragma omp parallel for if (nsubset * nj > 100000)
95
95
  for (int64_t si = 0; si < nsubset; si++) {
96
- T i = subset[si];
96
+ TI i = subset[si];
97
97
  T* __restrict simi = get_val(i);
98
98
  TI* __restrict idxi = get_ids(i);
99
99
  const T* ip_line = vin + si * nj;
@@ -136,6 +136,8 @@ void HeapArray<C>::per_line_extrema(T* out_val, TI* out_ids) const {
136
136
 
137
137
  template struct HeapArray<CMin<float, int64_t>>;
138
138
  template struct HeapArray<CMax<float, int64_t>>;
139
+ template struct HeapArray<CMin<float, int32_t>>;
140
+ template struct HeapArray<CMax<float, int32_t>>;
139
141
  template struct HeapArray<CMin<int, int64_t>>;
140
142
  template struct HeapArray<CMax<int, int64_t>>;
141
143
 
@@ -9,6 +9,7 @@
9
9
 
10
10
  #include <condition_variable>
11
11
  #include <deque>
12
+ #include <functional>
12
13
  #include <future>
13
14
  #include <thread>
14
15