faiss 0.2.7 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/ext/faiss/extconf.rb +9 -2
- data/ext/faiss/index.cpp +1 -1
- data/ext/faiss/index_binary.cpp +2 -2
- data/ext/faiss/product_quantizer.cpp +1 -1
- data/lib/faiss/version.rb +1 -1
- data/lib/faiss.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +7 -7
- data/vendor/faiss/faiss/AutoTune.h +0 -1
- data/vendor/faiss/faiss/Clustering.cpp +4 -18
- data/vendor/faiss/faiss/Clustering.h +31 -21
- data/vendor/faiss/faiss/IVFlib.cpp +22 -11
- data/vendor/faiss/faiss/Index.cpp +1 -1
- data/vendor/faiss/faiss/Index.h +20 -5
- data/vendor/faiss/faiss/Index2Layer.cpp +7 -7
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +176 -166
- data/vendor/faiss/faiss/IndexAdditiveQuantizerFastScan.cpp +15 -15
- data/vendor/faiss/faiss/IndexBinary.cpp +9 -4
- data/vendor/faiss/faiss/IndexBinary.h +8 -19
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +2 -1
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +24 -31
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +25 -50
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +106 -187
- data/vendor/faiss/faiss/IndexFastScan.cpp +90 -159
- data/vendor/faiss/faiss/IndexFastScan.h +9 -8
- data/vendor/faiss/faiss/IndexFlat.cpp +195 -3
- data/vendor/faiss/faiss/IndexFlat.h +20 -1
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +11 -0
- data/vendor/faiss/faiss/IndexFlatCodes.h +3 -1
- data/vendor/faiss/faiss/IndexHNSW.cpp +112 -316
- data/vendor/faiss/faiss/IndexHNSW.h +12 -48
- data/vendor/faiss/faiss/IndexIDMap.cpp +69 -28
- data/vendor/faiss/faiss/IndexIDMap.h +24 -2
- data/vendor/faiss/faiss/IndexIVF.cpp +159 -53
- data/vendor/faiss/faiss/IndexIVF.h +37 -5
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +18 -26
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +3 -2
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.cpp +19 -46
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizerFastScan.h +4 -3
- data/vendor/faiss/faiss/IndexIVFFastScan.cpp +433 -405
- data/vendor/faiss/faiss/IndexIVFFastScan.h +56 -26
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +15 -5
- data/vendor/faiss/faiss/IndexIVFFlat.h +3 -2
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.cpp +172 -0
- data/vendor/faiss/faiss/IndexIVFIndependentQuantizer.h +56 -0
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +78 -122
- data/vendor/faiss/faiss/IndexIVFPQ.h +6 -7
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +18 -50
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +4 -3
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +45 -29
- data/vendor/faiss/faiss/IndexIVFPQR.h +5 -2
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +25 -27
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +6 -6
- data/vendor/faiss/faiss/IndexLSH.cpp +14 -16
- data/vendor/faiss/faiss/IndexNNDescent.cpp +3 -4
- data/vendor/faiss/faiss/IndexNSG.cpp +11 -27
- data/vendor/faiss/faiss/IndexNSG.h +10 -10
- data/vendor/faiss/faiss/IndexPQ.cpp +72 -88
- data/vendor/faiss/faiss/IndexPQ.h +1 -4
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +1 -1
- data/vendor/faiss/faiss/IndexPreTransform.cpp +25 -31
- data/vendor/faiss/faiss/IndexRefine.cpp +49 -19
- data/vendor/faiss/faiss/IndexRefine.h +7 -0
- data/vendor/faiss/faiss/IndexReplicas.cpp +23 -26
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +22 -16
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +6 -4
- data/vendor/faiss/faiss/IndexShards.cpp +21 -29
- data/vendor/faiss/faiss/IndexShardsIVF.cpp +1 -2
- data/vendor/faiss/faiss/MatrixStats.cpp +17 -32
- data/vendor/faiss/faiss/MatrixStats.h +21 -9
- data/vendor/faiss/faiss/MetaIndexes.cpp +35 -35
- data/vendor/faiss/faiss/VectorTransform.cpp +13 -26
- data/vendor/faiss/faiss/VectorTransform.h +7 -7
- data/vendor/faiss/faiss/clone_index.cpp +15 -10
- data/vendor/faiss/faiss/clone_index.h +3 -0
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +87 -4
- data/vendor/faiss/faiss/gpu/GpuCloner.h +22 -0
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +7 -0
- data/vendor/faiss/faiss/gpu/GpuDistance.h +46 -38
- data/vendor/faiss/faiss/gpu/GpuIndex.h +28 -4
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +4 -4
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +8 -9
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +18 -3
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +22 -11
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +1 -3
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +24 -3
- data/vendor/faiss/faiss/gpu/GpuResources.h +39 -11
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +117 -17
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +57 -3
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +1 -1
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +25 -0
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +129 -9
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +267 -40
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +299 -208
- data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +1 -0
- data/vendor/faiss/faiss/gpu/utils/RaftUtils.h +75 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +3 -1
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +5 -5
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +1 -1
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +1 -2
- data/vendor/faiss/faiss/impl/DistanceComputer.h +24 -1
- data/vendor/faiss/faiss/impl/FaissException.h +13 -34
- data/vendor/faiss/faiss/impl/HNSW.cpp +321 -70
- data/vendor/faiss/faiss/impl/HNSW.h +9 -8
- data/vendor/faiss/faiss/impl/IDSelector.h +4 -4
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +3 -1
- data/vendor/faiss/faiss/impl/NNDescent.cpp +29 -19
- data/vendor/faiss/faiss/impl/NSG.h +1 -1
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +14 -12
- data/vendor/faiss/faiss/impl/ProductAdditiveQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +24 -22
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +1 -1
- data/vendor/faiss/faiss/impl/Quantizer.h +1 -1
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +27 -1015
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +5 -63
- data/vendor/faiss/faiss/impl/ResultHandler.h +232 -176
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +444 -104
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +0 -8
- data/vendor/faiss/faiss/impl/code_distance/code_distance-avx2.h +280 -42
- data/vendor/faiss/faiss/impl/code_distance/code_distance-generic.h +21 -14
- data/vendor/faiss/faiss/impl/code_distance/code_distance.h +22 -12
- data/vendor/faiss/faiss/impl/index_read.cpp +45 -19
- data/vendor/faiss/faiss/impl/index_write.cpp +60 -41
- data/vendor/faiss/faiss/impl/io.cpp +10 -10
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +1 -1
- data/vendor/faiss/faiss/impl/platform_macros.h +18 -1
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +3 -0
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +7 -6
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +52 -38
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +40 -49
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.cpp +960 -0
- data/vendor/faiss/faiss/impl/residual_quantizer_encode_steps.h +176 -0
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +374 -202
- data/vendor/faiss/faiss/index_factory.cpp +10 -7
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +1 -1
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +27 -9
- data/vendor/faiss/faiss/invlists/InvertedLists.h +12 -3
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +3 -3
- data/vendor/faiss/faiss/python/python_callbacks.cpp +1 -1
- data/vendor/faiss/faiss/utils/Heap.cpp +3 -1
- data/vendor/faiss/faiss/utils/WorkerThread.h +1 -0
- data/vendor/faiss/faiss/utils/distances.cpp +128 -74
- data/vendor/faiss/faiss/utils/distances.h +81 -4
- data/vendor/faiss/faiss/utils/distances_fused/avx512.cpp +5 -5
- data/vendor/faiss/faiss/utils/distances_fused/avx512.h +2 -2
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.cpp +2 -2
- data/vendor/faiss/faiss/utils/distances_fused/distances_fused.h +1 -1
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.cpp +5 -5
- data/vendor/faiss/faiss/utils/distances_fused/simdlib_based.h +1 -1
- data/vendor/faiss/faiss/utils/distances_simd.cpp +428 -70
- data/vendor/faiss/faiss/utils/fp16-arm.h +29 -0
- data/vendor/faiss/faiss/utils/fp16.h +2 -0
- data/vendor/faiss/faiss/utils/hamming.cpp +162 -110
- data/vendor/faiss/faiss/utils/hamming.h +58 -0
- data/vendor/faiss/faiss/utils/hamming_distance/avx2-inl.h +16 -89
- data/vendor/faiss/faiss/utils/hamming_distance/common.h +1 -0
- data/vendor/faiss/faiss/utils/hamming_distance/generic-inl.h +15 -87
- data/vendor/faiss/faiss/utils/hamming_distance/hamdis-inl.h +57 -0
- data/vendor/faiss/faiss/utils/hamming_distance/neon-inl.h +14 -104
- data/vendor/faiss/faiss/utils/partitioning.cpp +3 -4
- data/vendor/faiss/faiss/utils/prefetch.h +77 -0
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +0 -14
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +0 -6
- data/vendor/faiss/faiss/utils/simdlib_neon.h +72 -77
- data/vendor/faiss/faiss/utils/sorting.cpp +140 -5
- data/vendor/faiss/faiss/utils/sorting.h +27 -0
- data/vendor/faiss/faiss/utils/utils.cpp +112 -6
- data/vendor/faiss/faiss/utils/utils.h +57 -20
- metadata +11 -4
@@ -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
|
-
|
443
|
+
|
444
|
+
if (match("PQ([0-9]+)(x[0-9]+)?(np)?")) {
|
444
445
|
int M = std::stoi(sm[1].str());
|
445
|
-
|
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[
|
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
|
-
|
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[
|
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
|
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
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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(
|
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
|
-
}
|
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
|
-
}
|
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(
|
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(
|
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 =
|
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 =
|
536
|
+
size_t begin_next = ((size_t)1) << 60;
|
537
537
|
if (it != slots.end()) {
|
538
538
|
begin_next = it->offset;
|
539
539
|
}
|
@@ -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
|
-
|
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
|
|