faiss 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/ext/faiss/extconf.rb +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/benchs/bench_6bit_codec.cpp +80 -0
- data/vendor/faiss/c_api/AutoTune_c.h +2 -0
- data/vendor/faiss/c_api/IndexShards_c.cpp +0 -6
- data/vendor/faiss/c_api/IndexShards_c.h +1 -4
- data/vendor/faiss/c_api/gpu/GpuAutoTune_c.cpp +4 -2
- data/vendor/faiss/c_api/gpu/GpuClonerOptions_c.cpp +1 -1
- data/vendor/faiss/c_api/gpu/GpuIndex_c.cpp +1 -1
- data/vendor/faiss/c_api/gpu/GpuResources_c.cpp +1 -1
- data/vendor/faiss/c_api/gpu/StandardGpuResources_c.cpp +1 -1
- data/vendor/faiss/demos/demo_imi_flat.cpp +5 -2
- data/vendor/faiss/demos/demo_imi_pq.cpp +6 -2
- data/vendor/faiss/demos/demo_ivfpq_indexing.cpp +7 -2
- data/vendor/faiss/{AutoTune.cpp → faiss/AutoTune.cpp} +9 -9
- data/vendor/faiss/{AutoTune.h → faiss/AutoTune.h} +0 -0
- data/vendor/faiss/{Clustering.cpp → faiss/Clustering.cpp} +13 -12
- data/vendor/faiss/{Clustering.h → faiss/Clustering.h} +0 -0
- data/vendor/faiss/{DirectMap.cpp → faiss/DirectMap.cpp} +0 -0
- data/vendor/faiss/{DirectMap.h → faiss/DirectMap.h} +0 -0
- data/vendor/faiss/{IVFlib.cpp → faiss/IVFlib.cpp} +86 -11
- data/vendor/faiss/{IVFlib.h → faiss/IVFlib.h} +26 -8
- data/vendor/faiss/{Index.cpp → faiss/Index.cpp} +0 -0
- data/vendor/faiss/{Index.h → faiss/Index.h} +1 -1
- data/vendor/faiss/{Index2Layer.cpp → faiss/Index2Layer.cpp} +12 -11
- data/vendor/faiss/{Index2Layer.h → faiss/Index2Layer.h} +0 -0
- data/vendor/faiss/{IndexBinary.cpp → faiss/IndexBinary.cpp} +2 -1
- data/vendor/faiss/{IndexBinary.h → faiss/IndexBinary.h} +0 -0
- data/vendor/faiss/{IndexBinaryFlat.cpp → faiss/IndexBinaryFlat.cpp} +0 -0
- data/vendor/faiss/{IndexBinaryFlat.h → faiss/IndexBinaryFlat.h} +0 -0
- data/vendor/faiss/{IndexBinaryFromFloat.cpp → faiss/IndexBinaryFromFloat.cpp} +1 -0
- data/vendor/faiss/{IndexBinaryFromFloat.h → faiss/IndexBinaryFromFloat.h} +0 -0
- data/vendor/faiss/{IndexBinaryHNSW.cpp → faiss/IndexBinaryHNSW.cpp} +1 -2
- data/vendor/faiss/{IndexBinaryHNSW.h → faiss/IndexBinaryHNSW.h} +0 -0
- data/vendor/faiss/{IndexBinaryHash.cpp → faiss/IndexBinaryHash.cpp} +16 -7
- data/vendor/faiss/{IndexBinaryHash.h → faiss/IndexBinaryHash.h} +2 -1
- data/vendor/faiss/{IndexBinaryIVF.cpp → faiss/IndexBinaryIVF.cpp} +10 -16
- data/vendor/faiss/{IndexBinaryIVF.h → faiss/IndexBinaryIVF.h} +1 -1
- data/vendor/faiss/{IndexFlat.cpp → faiss/IndexFlat.cpp} +0 -0
- data/vendor/faiss/{IndexFlat.h → faiss/IndexFlat.h} +0 -0
- data/vendor/faiss/{IndexHNSW.cpp → faiss/IndexHNSW.cpp} +63 -32
- data/vendor/faiss/{IndexHNSW.h → faiss/IndexHNSW.h} +0 -0
- data/vendor/faiss/{IndexIVF.cpp → faiss/IndexIVF.cpp} +129 -46
- data/vendor/faiss/{IndexIVF.h → faiss/IndexIVF.h} +7 -3
- data/vendor/faiss/{IndexIVFFlat.cpp → faiss/IndexIVFFlat.cpp} +6 -5
- data/vendor/faiss/{IndexIVFFlat.h → faiss/IndexIVFFlat.h} +0 -0
- data/vendor/faiss/{IndexIVFPQ.cpp → faiss/IndexIVFPQ.cpp} +9 -8
- data/vendor/faiss/{IndexIVFPQ.h → faiss/IndexIVFPQ.h} +4 -2
- data/vendor/faiss/{IndexIVFPQR.cpp → faiss/IndexIVFPQR.cpp} +3 -1
- data/vendor/faiss/{IndexIVFPQR.h → faiss/IndexIVFPQR.h} +0 -0
- data/vendor/faiss/{IndexIVFSpectralHash.cpp → faiss/IndexIVFSpectralHash.cpp} +1 -1
- data/vendor/faiss/{IndexIVFSpectralHash.h → faiss/IndexIVFSpectralHash.h} +0 -0
- data/vendor/faiss/{IndexLSH.cpp → faiss/IndexLSH.cpp} +0 -0
- data/vendor/faiss/{IndexLSH.h → faiss/IndexLSH.h} +0 -0
- data/vendor/faiss/{IndexLattice.cpp → faiss/IndexLattice.cpp} +0 -0
- data/vendor/faiss/{IndexLattice.h → faiss/IndexLattice.h} +0 -0
- data/vendor/faiss/{IndexPQ.cpp → faiss/IndexPQ.cpp} +6 -6
- data/vendor/faiss/{IndexPQ.h → faiss/IndexPQ.h} +3 -1
- data/vendor/faiss/{IndexPreTransform.cpp → faiss/IndexPreTransform.cpp} +0 -0
- data/vendor/faiss/{IndexPreTransform.h → faiss/IndexPreTransform.h} +0 -0
- data/vendor/faiss/{IndexReplicas.cpp → faiss/IndexReplicas.cpp} +102 -10
- data/vendor/faiss/{IndexReplicas.h → faiss/IndexReplicas.h} +6 -0
- data/vendor/faiss/{IndexScalarQuantizer.cpp → faiss/IndexScalarQuantizer.cpp} +3 -3
- data/vendor/faiss/{IndexScalarQuantizer.h → faiss/IndexScalarQuantizer.h} +0 -0
- data/vendor/faiss/{IndexShards.cpp → faiss/IndexShards.cpp} +37 -12
- data/vendor/faiss/{IndexShards.h → faiss/IndexShards.h} +3 -4
- data/vendor/faiss/{InvertedLists.cpp → faiss/InvertedLists.cpp} +2 -2
- data/vendor/faiss/{InvertedLists.h → faiss/InvertedLists.h} +1 -0
- data/vendor/faiss/{MatrixStats.cpp → faiss/MatrixStats.cpp} +0 -0
- data/vendor/faiss/{MatrixStats.h → faiss/MatrixStats.h} +0 -0
- data/vendor/faiss/{MetaIndexes.cpp → faiss/MetaIndexes.cpp} +5 -3
- data/vendor/faiss/{MetaIndexes.h → faiss/MetaIndexes.h} +0 -0
- data/vendor/faiss/{MetricType.h → faiss/MetricType.h} +0 -0
- data/vendor/faiss/{OnDiskInvertedLists.cpp → faiss/OnDiskInvertedLists.cpp} +141 -3
- data/vendor/faiss/{OnDiskInvertedLists.h → faiss/OnDiskInvertedLists.h} +27 -7
- data/vendor/faiss/{VectorTransform.cpp → faiss/VectorTransform.cpp} +4 -3
- data/vendor/faiss/{VectorTransform.h → faiss/VectorTransform.h} +0 -0
- data/vendor/faiss/{clone_index.cpp → faiss/clone_index.cpp} +0 -0
- data/vendor/faiss/{clone_index.h → faiss/clone_index.h} +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuAutoTune.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuAutoTune.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuCloner.cpp +14 -14
- data/vendor/faiss/{gpu → faiss/gpu}/GpuCloner.h +6 -7
- data/vendor/faiss/{gpu → faiss/gpu}/GpuClonerOptions.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuClonerOptions.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuDistance.h +12 -4
- data/vendor/faiss/{gpu → faiss/gpu}/GpuFaissAssert.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndex.h +3 -9
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexBinaryFlat.h +7 -7
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexFlat.h +35 -10
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVF.h +1 -2
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFFlat.h +4 -3
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFPQ.h +21 -4
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndexIVFScalarQuantizer.h +4 -3
- data/vendor/faiss/{gpu → faiss/gpu}/GpuIndicesOptions.h +0 -0
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +200 -0
- data/vendor/faiss/faiss/gpu/GpuResources.h +264 -0
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +572 -0
- data/vendor/faiss/{gpu → faiss/gpu}/StandardGpuResources.h +83 -15
- data/vendor/faiss/{gpu → faiss/gpu}/impl/RemapIndices.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/impl/RemapIndices.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/perf/IndexWrapper-inl.h +1 -1
- data/vendor/faiss/{gpu → faiss/gpu}/perf/IndexWrapper.h +1 -1
- data/vendor/faiss/{gpu → faiss/gpu}/perf/PerfClustering.cpp +1 -1
- data/vendor/faiss/{gpu → faiss/gpu}/perf/PerfIVFPQAdd.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/perf/WriteIndex.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexBinaryFlat.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexFlat.cpp +1 -1
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexIVFFlat.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuIndexIVFPQ.cpp +141 -52
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestGpuMemoryException.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestUtils.cpp +4 -2
- data/vendor/faiss/{gpu → faiss/gpu}/test/TestUtils.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/test/demo_ivfpq_indexing_gpu.cpp +7 -5
- data/vendor/faiss/{gpu → faiss/gpu}/utils/DeviceUtils.h +1 -1
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +213 -0
- data/vendor/faiss/{gpu → faiss/gpu}/utils/StackDeviceMemory.h +25 -40
- data/vendor/faiss/{gpu → faiss/gpu}/utils/StaticUtils.h +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/utils/Timer.cpp +0 -0
- data/vendor/faiss/{gpu → faiss/gpu}/utils/Timer.h +0 -0
- data/vendor/faiss/{impl → faiss/impl}/AuxIndexStructures.cpp +1 -0
- data/vendor/faiss/{impl → faiss/impl}/AuxIndexStructures.h +3 -1
- data/vendor/faiss/{impl → faiss/impl}/FaissAssert.h +1 -0
- data/vendor/faiss/{impl → faiss/impl}/FaissException.cpp +26 -0
- data/vendor/faiss/{impl → faiss/impl}/FaissException.h +4 -0
- data/vendor/faiss/{impl → faiss/impl}/HNSW.cpp +26 -26
- data/vendor/faiss/{impl → faiss/impl}/HNSW.h +19 -11
- data/vendor/faiss/{impl → faiss/impl}/PolysemousTraining.cpp +1 -1
- data/vendor/faiss/{impl → faiss/impl}/PolysemousTraining.h +1 -1
- data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer-inl.h +0 -1
- data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer.cpp +9 -9
- data/vendor/faiss/{impl → faiss/impl}/ProductQuantizer.h +0 -0
- data/vendor/faiss/{impl → faiss/impl}/ScalarQuantizer.cpp +63 -39
- data/vendor/faiss/{impl → faiss/impl}/ScalarQuantizer.h +1 -1
- data/vendor/faiss/{impl → faiss/impl}/ThreadedIndex-inl.h +0 -0
- data/vendor/faiss/{impl → faiss/impl}/ThreadedIndex.h +0 -0
- data/vendor/faiss/{impl → faiss/impl}/index_read.cpp +99 -116
- data/vendor/faiss/{impl → faiss/impl}/index_write.cpp +15 -50
- data/vendor/faiss/{impl → faiss/impl}/io.cpp +15 -10
- data/vendor/faiss/{impl → faiss/impl}/io.h +22 -8
- data/vendor/faiss/faiss/impl/io_macros.h +57 -0
- data/vendor/faiss/{impl → faiss/impl}/lattice_Zn.cpp +52 -36
- data/vendor/faiss/{impl → faiss/impl}/lattice_Zn.h +3 -3
- data/vendor/faiss/faiss/impl/platform_macros.h +24 -0
- data/vendor/faiss/{index_factory.cpp → faiss/index_factory.cpp} +33 -12
- data/vendor/faiss/{index_factory.h → faiss/index_factory.h} +0 -0
- data/vendor/faiss/{index_io.h → faiss/index_io.h} +55 -1
- data/vendor/faiss/faiss/python/python_callbacks.cpp +112 -0
- data/vendor/faiss/faiss/python/python_callbacks.h +45 -0
- data/vendor/faiss/{utils → faiss/utils}/Heap.cpp +5 -5
- data/vendor/faiss/{utils → faiss/utils}/Heap.h +1 -3
- data/vendor/faiss/{utils → faiss/utils}/WorkerThread.cpp +0 -0
- data/vendor/faiss/{utils → faiss/utils}/WorkerThread.h +0 -0
- data/vendor/faiss/{utils → faiss/utils}/distances.cpp +28 -13
- data/vendor/faiss/{utils → faiss/utils}/distances.h +2 -1
- data/vendor/faiss/{utils → faiss/utils}/distances_simd.cpp +5 -5
- data/vendor/faiss/{utils → faiss/utils}/extra_distances.cpp +8 -7
- data/vendor/faiss/{utils → faiss/utils}/extra_distances.h +0 -0
- data/vendor/faiss/{utils → faiss/utils}/hamming-inl.h +1 -3
- data/vendor/faiss/{utils → faiss/utils}/hamming.cpp +8 -7
- data/vendor/faiss/{utils → faiss/utils}/hamming.h +7 -1
- data/vendor/faiss/{utils → faiss/utils}/random.cpp +5 -5
- data/vendor/faiss/{utils → faiss/utils}/random.h +0 -0
- data/vendor/faiss/{utils → faiss/utils}/utils.cpp +27 -28
- data/vendor/faiss/{utils → faiss/utils}/utils.h +4 -0
- data/vendor/faiss/misc/test_blas.cpp +4 -1
- data/vendor/faiss/tests/test_binary_flat.cpp +0 -2
- data/vendor/faiss/tests/test_dealloc_invlists.cpp +6 -1
- data/vendor/faiss/tests/test_ivfpq_codec.cpp +4 -1
- data/vendor/faiss/tests/test_ivfpq_indexing.cpp +6 -4
- data/vendor/faiss/tests/test_lowlevel_ivf.cpp +12 -5
- data/vendor/faiss/tests/test_merge.cpp +6 -3
- data/vendor/faiss/tests/test_ondisk_ivf.cpp +7 -2
- data/vendor/faiss/tests/test_pairs_decoding.cpp +5 -1
- data/vendor/faiss/tests/test_params_override.cpp +7 -2
- data/vendor/faiss/tests/test_sliding_ivf.cpp +10 -4
- data/vendor/faiss/tutorial/cpp/1-Flat.cpp +14 -8
- data/vendor/faiss/tutorial/cpp/2-IVFFlat.cpp +11 -7
- data/vendor/faiss/tutorial/cpp/3-IVFPQ.cpp +12 -7
- data/vendor/faiss/tutorial/cpp/4-GPU.cpp +6 -3
- data/vendor/faiss/tutorial/cpp/5-Multiple-GPUs.cpp +7 -3
- metadata +154 -153
- data/vendor/faiss/gpu/GpuResources.cpp +0 -52
- data/vendor/faiss/gpu/GpuResources.h +0 -73
- data/vendor/faiss/gpu/StandardGpuResources.cpp +0 -303
- data/vendor/faiss/gpu/utils/DeviceMemory.cpp +0 -77
- data/vendor/faiss/gpu/utils/DeviceMemory.h +0 -71
- data/vendor/faiss/gpu/utils/MemorySpace.cpp +0 -89
- data/vendor/faiss/gpu/utils/MemorySpace.h +0 -44
- data/vendor/faiss/gpu/utils/StackDeviceMemory.cpp +0 -239
@@ -10,6 +10,10 @@
|
|
10
10
|
#include <faiss/impl/FaissException.h>
|
11
11
|
#include <sstream>
|
12
12
|
|
13
|
+
#ifdef __GNUG__
|
14
|
+
#include <cxxabi.h>
|
15
|
+
#endif
|
16
|
+
|
13
17
|
namespace faiss {
|
14
18
|
|
15
19
|
FaissException::FaissException(const std::string& m)
|
@@ -63,4 +67,26 @@ void handleExceptions(
|
|
63
67
|
}
|
64
68
|
}
|
65
69
|
|
70
|
+
|
71
|
+
// From
|
72
|
+
// https://stackoverflow.com/questions/281818/unmangling-the-result-of-stdtype-infoname
|
73
|
+
|
74
|
+
std::string demangle_cpp_symbol(const char* name) {
|
75
|
+
#ifdef __GNUG__
|
76
|
+
int status = -1;
|
77
|
+
const char * res = abi::__cxa_demangle(name, nullptr, nullptr, &status);
|
78
|
+
std::string sres;
|
79
|
+
if (status == 0) {
|
80
|
+
sres = res;
|
81
|
+
}
|
82
|
+
free((void*)res);
|
83
|
+
return sres;
|
84
|
+
#else
|
85
|
+
// don't know how to do this on other platforms
|
86
|
+
return std::string(name);
|
87
|
+
#endif
|
66
88
|
}
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
} // namespace
|
@@ -157,11 +157,11 @@ void HNSW::print_neighbor_stats(int level) const
|
|
157
157
|
}
|
158
158
|
}
|
159
159
|
float normalizer = n_node;
|
160
|
-
printf(" nb of nodes at that level %
|
161
|
-
printf(" neighbors per node: %.2f (%
|
160
|
+
printf(" nb of nodes at that level %zd\n", n_node);
|
161
|
+
printf(" neighbors per node: %.2f (%zd)\n",
|
162
162
|
tot_neigh / normalizer, tot_neigh);
|
163
163
|
printf(" nb of reciprocal neighbors: %.2f\n", tot_reciprocal / normalizer);
|
164
|
-
printf(" nb of neighbors that are also neighbor-of-neighbors: %.2f (%
|
164
|
+
printf(" nb of neighbors that are also neighbor-of-neighbors: %.2f (%zd)\n",
|
165
165
|
tot_common / normalizer, tot_common);
|
166
166
|
|
167
167
|
|
@@ -181,7 +181,7 @@ void HNSW::fill_with_random_links(size_t n)
|
|
181
181
|
elts.push_back(i);
|
182
182
|
}
|
183
183
|
}
|
184
|
-
printf ("linking %
|
184
|
+
printf ("linking %zd elements in level %d\n",
|
185
185
|
elts.size(), level);
|
186
186
|
|
187
187
|
if (elts.size() == 1) continue;
|
@@ -527,6 +527,7 @@ int HNSW::search_from_candidates(
|
|
527
527
|
idx_t *I, float *D,
|
528
528
|
MinimaxHeap& candidates,
|
529
529
|
VisitedTable& vt,
|
530
|
+
HNSWStats& stats,
|
530
531
|
int level, int nres_in) const
|
531
532
|
{
|
532
533
|
int nres = nres_in;
|
@@ -590,14 +591,11 @@ int HNSW::search_from_candidates(
|
|
590
591
|
}
|
591
592
|
|
592
593
|
if (level == 0) {
|
593
|
-
|
594
|
-
{
|
595
|
-
|
596
|
-
if (candidates.size() == 0) {
|
597
|
-
hnsw_stats.n2 ++;
|
598
|
-
}
|
599
|
-
hnsw_stats.n3 += ndis;
|
594
|
+
stats.n1 ++;
|
595
|
+
if (candidates.size() == 0) {
|
596
|
+
stats.n2 ++;
|
600
597
|
}
|
598
|
+
stats.n3 += ndis;
|
601
599
|
}
|
602
600
|
|
603
601
|
return nres;
|
@@ -612,7 +610,8 @@ std::priority_queue<HNSW::Node> HNSW::search_from_candidate_unbounded(
|
|
612
610
|
const Node& node,
|
613
611
|
DistanceComputer& qdis,
|
614
612
|
int ef,
|
615
|
-
VisitedTable *vt
|
613
|
+
VisitedTable *vt,
|
614
|
+
HNSWStats& stats) const
|
616
615
|
{
|
617
616
|
int ndis = 0;
|
618
617
|
std::priority_queue<Node> top_candidates;
|
@@ -663,22 +662,21 @@ std::priority_queue<HNSW::Node> HNSW::search_from_candidate_unbounded(
|
|
663
662
|
}
|
664
663
|
}
|
665
664
|
|
666
|
-
|
667
|
-
{
|
668
|
-
++
|
669
|
-
if (candidates.size() == 0) {
|
670
|
-
++hnsw_stats.n2;
|
671
|
-
}
|
672
|
-
hnsw_stats.n3 += ndis;
|
665
|
+
++stats.n1;
|
666
|
+
if (candidates.size() == 0) {
|
667
|
+
++stats.n2;
|
673
668
|
}
|
669
|
+
stats.n3 += ndis;
|
674
670
|
|
675
671
|
return top_candidates;
|
676
672
|
}
|
677
673
|
|
678
|
-
|
679
|
-
|
680
|
-
|
674
|
+
HNSWStats HNSW::search(DistanceComputer& qdis, int k,
|
675
|
+
idx_t *I, float *D,
|
676
|
+
VisitedTable& vt) const
|
681
677
|
{
|
678
|
+
HNSWStats stats;
|
679
|
+
|
682
680
|
if (upper_beam == 1) {
|
683
681
|
|
684
682
|
// greedy search on upper levels
|
@@ -695,11 +693,11 @@ void HNSW::search(DistanceComputer& qdis, int k,
|
|
695
693
|
|
696
694
|
candidates.push(nearest, d_nearest);
|
697
695
|
|
698
|
-
search_from_candidates(qdis, k, I, D, candidates, vt, 0);
|
696
|
+
search_from_candidates(qdis, k, I, D, candidates, vt, stats, 0);
|
699
697
|
} else {
|
700
698
|
std::priority_queue<Node> top_candidates =
|
701
699
|
search_from_candidate_unbounded(Node(d_nearest, nearest),
|
702
|
-
qdis, ef, &vt);
|
700
|
+
qdis, ef, &vt, stats);
|
703
701
|
|
704
702
|
while (top_candidates.size() > k) {
|
705
703
|
top_candidates.pop();
|
@@ -739,17 +737,19 @@ void HNSW::search(DistanceComputer& qdis, int k,
|
|
739
737
|
}
|
740
738
|
|
741
739
|
if (level == 0) {
|
742
|
-
nres = search_from_candidates(qdis, k, I, D, candidates, vt, 0);
|
740
|
+
nres = search_from_candidates(qdis, k, I, D, candidates, vt, stats, 0);
|
743
741
|
} else {
|
744
742
|
nres = search_from_candidates(
|
745
743
|
qdis, candidates_size,
|
746
744
|
I_to_next.data(), D_to_next.data(),
|
747
|
-
candidates, vt, level
|
745
|
+
candidates, vt, stats, level
|
748
746
|
);
|
749
747
|
}
|
750
748
|
vt.advance();
|
751
749
|
}
|
752
750
|
}
|
751
|
+
|
752
|
+
return stats;
|
753
753
|
}
|
754
754
|
|
755
755
|
|
@@ -19,6 +19,7 @@
|
|
19
19
|
#include <faiss/impl/FaissAssert.h>
|
20
20
|
#include <faiss/utils/random.h>
|
21
21
|
#include <faiss/utils/Heap.h>
|
22
|
+
#include <faiss/impl/platform_macros.h>
|
22
23
|
|
23
24
|
|
24
25
|
namespace faiss {
|
@@ -43,6 +44,7 @@ namespace faiss {
|
|
43
44
|
|
44
45
|
struct VisitedTable;
|
45
46
|
struct DistanceComputer; // from AuxIndexStructures
|
47
|
+
struct HNSWStats;
|
46
48
|
|
47
49
|
struct HNSW {
|
48
50
|
/// internal storage of vectors (32 bits: this is expensive)
|
@@ -186,19 +188,20 @@ struct HNSW {
|
|
186
188
|
idx_t *I, float *D,
|
187
189
|
MinimaxHeap& candidates,
|
188
190
|
VisitedTable &vt,
|
191
|
+
HNSWStats &stats,
|
189
192
|
int level, int nres_in = 0) const;
|
190
193
|
|
191
194
|
std::priority_queue<Node> search_from_candidate_unbounded(
|
192
195
|
const Node& node,
|
193
196
|
DistanceComputer& qdis,
|
194
197
|
int ef,
|
195
|
-
VisitedTable *vt
|
196
|
-
|
198
|
+
VisitedTable *vt,
|
199
|
+
HNSWStats &stats) const;
|
197
200
|
|
198
201
|
/// search interface
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
+
HNSWStats search(DistanceComputer& qdis, int k,
|
203
|
+
idx_t *I, float *D,
|
204
|
+
VisitedTable &vt) const;
|
202
205
|
|
203
206
|
void reset();
|
204
207
|
|
@@ -254,22 +257,27 @@ struct HNSWStats {
|
|
254
257
|
size_t n1, n2, n3;
|
255
258
|
size_t ndis;
|
256
259
|
size_t nreorder;
|
257
|
-
bool view;
|
258
260
|
|
259
|
-
HNSWStats()
|
260
|
-
|
261
|
-
}
|
261
|
+
HNSWStats(size_t n1 = 0, size_t n2 = 0, size_t n3 = 0, size_t ndis = 0, size_t nreorder = 0)
|
262
|
+
: n1(n1), n2(n2), n3(n3), ndis(ndis), nreorder(nreorder) {}
|
262
263
|
|
263
264
|
void reset() {
|
264
265
|
n1 = n2 = n3 = 0;
|
265
266
|
ndis = 0;
|
266
267
|
nreorder = 0;
|
267
|
-
|
268
|
+
}
|
269
|
+
|
270
|
+
void combine(const HNSWStats& other) {
|
271
|
+
n1 += other.n1;
|
272
|
+
n2 += other.n2;
|
273
|
+
n3 += other.n3;
|
274
|
+
ndis += other.ndis;
|
275
|
+
nreorder += other.nreorder;
|
268
276
|
}
|
269
277
|
};
|
270
278
|
|
271
279
|
// global var that collects them all
|
272
|
-
extern HNSWStats hnsw_stats;
|
280
|
+
FAISS_API extern HNSWStats hnsw_stats;
|
273
281
|
|
274
282
|
|
275
283
|
} // namespace faiss
|
@@ -893,7 +893,7 @@ void PolysemousTraining::optimize_ranking (
|
|
893
893
|
ScopeDeleter1<PermutationObjective> del (obj);
|
894
894
|
|
895
895
|
if (verbose > 0) {
|
896
|
-
printf(" m=%d, nq=%
|
896
|
+
printf(" m=%d, nq=%zd, nb=%zd, intialize RankingScore "
|
897
897
|
"in %.3f ms\n",
|
898
898
|
m, nq, nb, getmillisecs () - t0);
|
899
899
|
}
|
@@ -101,7 +101,7 @@ struct RandomGenerator;
|
|
101
101
|
const SimulatedAnnealingParameters &p);
|
102
102
|
RandomGenerator *rnd;
|
103
103
|
|
104
|
-
/// remember
|
104
|
+
/// remember initial cost of optimization
|
105
105
|
double init_cost;
|
106
106
|
|
107
107
|
// main entry point. Perform the optimization loop, starting from
|
@@ -261,7 +261,7 @@ void ProductQuantizer::train (int n, const float * x)
|
|
261
261
|
train_type == Train_hypercube_pca) {
|
262
262
|
if (dsub < nbits) {
|
263
263
|
final_train_type = Train_default;
|
264
|
-
printf ("cannot train hypercube: nbits=%
|
264
|
+
printf ("cannot train hypercube: nbits=%zd > log2(d=%zd)\n",
|
265
265
|
nbits, dsub);
|
266
266
|
}
|
267
267
|
}
|
@@ -329,14 +329,14 @@ void ProductQuantizer::train (int n, const float * x)
|
|
329
329
|
|
330
330
|
template<class PQEncoder>
|
331
331
|
void compute_code(const ProductQuantizer& pq, const float *x, uint8_t *code) {
|
332
|
-
float distances
|
332
|
+
std::vector<float> distances(pq.ksub);
|
333
333
|
PQEncoder encoder(code, pq.nbits);
|
334
334
|
for (size_t m = 0; m < pq.M; m++) {
|
335
335
|
float mindis = 1e20;
|
336
336
|
uint64_t idxm = 0;
|
337
337
|
const float * xsub = x + m * pq.dsub;
|
338
338
|
|
339
|
-
fvec_L2sqr_ny(distances, xsub, pq.get_centroids(m, 0), pq.dsub, pq.ksub);
|
339
|
+
fvec_L2sqr_ny(distances.data(), xsub, pq.get_centroids(m, 0), pq.dsub, pq.ksub);
|
340
340
|
|
341
341
|
/* Find best centroid */
|
342
342
|
for (size_t i = 0; i < pq.ksub; i++) {
|
@@ -496,7 +496,7 @@ void ProductQuantizer::compute_codes (const float * x,
|
|
496
496
|
if (dsub < 16) { // simple direct computation
|
497
497
|
|
498
498
|
#pragma omp parallel for
|
499
|
-
for (
|
499
|
+
for (int64_t i = 0; i < n; i++)
|
500
500
|
compute_code (x + i * d, codes + i * code_size);
|
501
501
|
|
502
502
|
} else { // worthwile to use BLAS
|
@@ -505,7 +505,7 @@ void ProductQuantizer::compute_codes (const float * x,
|
|
505
505
|
compute_distance_tables (n, x, dis_tables);
|
506
506
|
|
507
507
|
#pragma omp parallel for
|
508
|
-
for (
|
508
|
+
for (int64_t i = 0; i < n; i++) {
|
509
509
|
uint8_t * code = codes + i * code_size;
|
510
510
|
const float * tab = dis_tables + i * ksub * M;
|
511
511
|
compute_code_from_distance_table (tab, code);
|
@@ -552,7 +552,7 @@ void ProductQuantizer::compute_distance_tables (
|
|
552
552
|
if (dsub < 16) {
|
553
553
|
|
554
554
|
#pragma omp parallel for
|
555
|
-
for (
|
555
|
+
for (int64_t i = 0; i < nx; i++) {
|
556
556
|
compute_distance_table (x + i * d, dis_tables + i * ksub * M);
|
557
557
|
}
|
558
558
|
|
@@ -577,7 +577,7 @@ void ProductQuantizer::compute_inner_prod_tables (
|
|
577
577
|
if (dsub < 16) {
|
578
578
|
|
579
579
|
#pragma omp parallel for
|
580
|
-
for (
|
580
|
+
for (int64_t i = 0; i < nx; i++) {
|
581
581
|
compute_inner_prod_table (x + i * d, dis_tables + i * ksub * M);
|
582
582
|
}
|
583
583
|
|
@@ -614,7 +614,7 @@ static void pq_knn_search_with_tables (
|
|
614
614
|
|
615
615
|
|
616
616
|
#pragma omp parallel for
|
617
|
-
for (
|
617
|
+
for (int64_t i = 0; i < nx; i++) {
|
618
618
|
/* query preparation for asymmetric search: compute look-up tables */
|
619
619
|
const float* dis_table = dis_tables + i * ksub * M;
|
620
620
|
|
@@ -728,7 +728,7 @@ void ProductQuantizer::search_sdc (const uint8_t * qcodes,
|
|
728
728
|
|
729
729
|
|
730
730
|
#pragma omp parallel for
|
731
|
-
for (
|
731
|
+
for (int64_t i = 0; i < nq; i++) {
|
732
732
|
|
733
733
|
/* Compute distances and keep smallest values */
|
734
734
|
idx_t * heap_ids = res->ids + i * k;
|
File without changes
|
@@ -39,11 +39,7 @@ namespace faiss {
|
|
39
39
|
* that hides the template mess.
|
40
40
|
********************************************************************/
|
41
41
|
|
42
|
-
#
|
43
|
-
#define USE_AVX
|
44
|
-
#endif
|
45
|
-
|
46
|
-
#ifdef __F16C__
|
42
|
+
#if defined(__F16C__) && defined(__AVX2__)
|
47
43
|
#define USE_F16C
|
48
44
|
#endif
|
49
45
|
|
@@ -72,7 +68,7 @@ struct Codec8bit {
|
|
72
68
|
return (code[i] + 0.5f) / 255.0f;
|
73
69
|
}
|
74
70
|
|
75
|
-
#ifdef
|
71
|
+
#ifdef __AVX2__
|
76
72
|
static __m256 decode_8_components (const uint8_t *code, int i) {
|
77
73
|
uint64_t c8 = *(uint64_t*)(code + i);
|
78
74
|
__m128i c4lo = _mm_cvtepu8_epi32 (_mm_set1_epi32(c8));
|
@@ -101,7 +97,7 @@ struct Codec4bit {
|
|
101
97
|
}
|
102
98
|
|
103
99
|
|
104
|
-
#ifdef
|
100
|
+
#ifdef __AVX2__
|
105
101
|
static __m256 decode_8_components (const uint8_t *code, int i) {
|
106
102
|
uint32_t c4 = *(uint32_t*)(code + (i >> 1));
|
107
103
|
uint32_t mask = 0x0f0f0f0f;
|
@@ -169,18 +165,38 @@ struct Codec6bit {
|
|
169
165
|
return (bits + 0.5f) / 63.0f;
|
170
166
|
}
|
171
167
|
|
172
|
-
#ifdef
|
168
|
+
#ifdef __AVX2__
|
169
|
+
|
170
|
+
/* Load 6 bytes that represent 8 6-bit values, return them as a
|
171
|
+
* 8*32 bit vector register */
|
172
|
+
static __m256i load6 (const uint16_t *code16) {
|
173
|
+
const __m128i perm = _mm_set_epi8(-1, 5, 5, 4, 4, 3, -1, 3, -1, 2, 2, 1, 1, 0, -1, 0);
|
174
|
+
const __m256i shifts = _mm256_set_epi32(2, 4, 6, 0, 2, 4, 6, 0);
|
175
|
+
|
176
|
+
// load 6 bytes
|
177
|
+
__m128i c1 = _mm_set_epi16(0, 0, 0, 0, 0, code16[2], code16[1], code16[0]);
|
178
|
+
|
179
|
+
// put in 8 * 32 bits
|
180
|
+
__m128i c2 = _mm_shuffle_epi8(c1, perm);
|
181
|
+
__m256i c3 = _mm256_cvtepi16_epi32(c2);
|
182
|
+
|
183
|
+
// shift and mask out useless bits
|
184
|
+
__m256i c4 = _mm256_srlv_epi32(c3, shifts);
|
185
|
+
__m256i c5 = _mm256_and_si256(_mm256_set1_epi32(63), c4);
|
186
|
+
return c5;
|
187
|
+
}
|
188
|
+
|
173
189
|
static __m256 decode_8_components (const uint8_t *code, int i) {
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
decode_component(code, i + 0));
|
190
|
+
__m256i i8 = load6 ((const uint16_t *)(code + (i >> 2) * 3));
|
191
|
+
__m256 f8 = _mm256_cvtepi32_ps (i8);
|
192
|
+
// this could also be done with bit manipulations but it is
|
193
|
+
// not obviously faster
|
194
|
+
__m256 half = _mm256_set1_ps (0.5f);
|
195
|
+
f8 += half;
|
196
|
+
__m256 one_63 = _mm256_set1_ps (1.f / 63.f);
|
197
|
+
return f8 * one_63;
|
183
198
|
}
|
199
|
+
|
184
200
|
#endif
|
185
201
|
};
|
186
202
|
|
@@ -326,12 +342,15 @@ struct QuantizerTemplate<Codec, true, 1>: ScalarQuantizer::Quantizer {
|
|
326
342
|
|
327
343
|
void encode_vector(const float* x, uint8_t* code) const final {
|
328
344
|
for (size_t i = 0; i < d; i++) {
|
329
|
-
float xi =
|
330
|
-
if (
|
331
|
-
xi =
|
332
|
-
|
333
|
-
|
334
|
-
|
345
|
+
float xi = 0;
|
346
|
+
if (vdiff != 0) {
|
347
|
+
xi = (x[i] - vmin) / vdiff;
|
348
|
+
if (xi < 0) {
|
349
|
+
xi = 0;
|
350
|
+
}
|
351
|
+
if (xi > 1.0) {
|
352
|
+
xi = 1.0;
|
353
|
+
}
|
335
354
|
}
|
336
355
|
Codec::encode_component(xi, code, i);
|
337
356
|
}
|
@@ -354,7 +373,7 @@ struct QuantizerTemplate<Codec, true, 1>: ScalarQuantizer::Quantizer {
|
|
354
373
|
|
355
374
|
|
356
375
|
|
357
|
-
#ifdef
|
376
|
+
#ifdef __AVX2__
|
358
377
|
|
359
378
|
template<class Codec>
|
360
379
|
struct QuantizerTemplate<Codec, true, 8>: QuantizerTemplate<Codec, true, 1> {
|
@@ -384,11 +403,16 @@ struct QuantizerTemplate<Codec, false, 1>: ScalarQuantizer::Quantizer {
|
|
384
403
|
|
385
404
|
void encode_vector(const float* x, uint8_t* code) const final {
|
386
405
|
for (size_t i = 0; i < d; i++) {
|
387
|
-
float xi =
|
388
|
-
if (
|
389
|
-
xi =
|
390
|
-
|
391
|
-
|
406
|
+
float xi = 0;
|
407
|
+
if (vdiff[i] != 0) {
|
408
|
+
xi = (x[i] - vmin[i]) / vdiff[i];
|
409
|
+
if (xi < 0) {
|
410
|
+
xi = 0;
|
411
|
+
}
|
412
|
+
if (xi > 1.0) {
|
413
|
+
xi = 1.0;
|
414
|
+
}
|
415
|
+
}
|
392
416
|
Codec::encode_component(xi, code, i);
|
393
417
|
}
|
394
418
|
}
|
@@ -409,7 +433,7 @@ struct QuantizerTemplate<Codec, false, 1>: ScalarQuantizer::Quantizer {
|
|
409
433
|
};
|
410
434
|
|
411
435
|
|
412
|
-
#ifdef
|
436
|
+
#ifdef __AVX2__
|
413
437
|
|
414
438
|
template<class Codec>
|
415
439
|
struct QuantizerTemplate<Codec, false, 8>: QuantizerTemplate<Codec, false, 1> {
|
@@ -513,7 +537,7 @@ struct Quantizer8bitDirect<1>: ScalarQuantizer::Quantizer {
|
|
513
537
|
|
514
538
|
};
|
515
539
|
|
516
|
-
#ifdef
|
540
|
+
#ifdef __AVX2__
|
517
541
|
|
518
542
|
template<>
|
519
543
|
struct Quantizer8bitDirect<8>: Quantizer8bitDirect<1> {
|
@@ -691,7 +715,7 @@ void train_NonUniform(RangeStat rs, float rs_arg,
|
|
691
715
|
float vexp = (vmax[j] - vmin[j]) * rs_arg;
|
692
716
|
vmin[j] -= vexp;
|
693
717
|
vmax[j] += vexp;
|
694
|
-
vdiff
|
718
|
+
vdiff[j] = vmax[j] - vmin[j];
|
695
719
|
}
|
696
720
|
} else {
|
697
721
|
// transpose
|
@@ -704,7 +728,7 @@ void train_NonUniform(RangeStat rs, float rs_arg,
|
|
704
728
|
}
|
705
729
|
std::vector<float> trained_d(2);
|
706
730
|
#pragma omp parallel for
|
707
|
-
for (
|
731
|
+
for (int j = 0; j < d; j++) {
|
708
732
|
train_Uniform(rs, rs_arg,
|
709
733
|
n, k, xt.data() + j * n,
|
710
734
|
trained_d);
|
@@ -760,7 +784,7 @@ struct SimilarityL2<1> {
|
|
760
784
|
};
|
761
785
|
|
762
786
|
|
763
|
-
#ifdef
|
787
|
+
#ifdef __AVX2__
|
764
788
|
template<>
|
765
789
|
struct SimilarityL2<8> {
|
766
790
|
static constexpr int simdwidth = 8;
|
@@ -835,7 +859,7 @@ struct SimilarityIP<1> {
|
|
835
859
|
}
|
836
860
|
};
|
837
861
|
|
838
|
-
#ifdef
|
862
|
+
#ifdef __AVX2__
|
839
863
|
|
840
864
|
template<>
|
841
865
|
struct SimilarityIP<8> {
|
@@ -915,7 +939,7 @@ struct DCTemplate<Quantizer, Similarity, 1> : SQDistanceComputer
|
|
915
939
|
for (size_t i = 0; i < quant.d; i++) {
|
916
940
|
float x1 = quant.reconstruct_component(code1, i);
|
917
941
|
float x2 = quant.reconstruct_component(code2, i);
|
918
|
-
|
942
|
+
sim.add_component_2(x1, x2);
|
919
943
|
}
|
920
944
|
return sim.result();
|
921
945
|
}
|
@@ -1058,7 +1082,7 @@ struct DistanceComputerByte<Similarity, 1> : SQDistanceComputer {
|
|
1058
1082
|
|
1059
1083
|
};
|
1060
1084
|
|
1061
|
-
#ifdef
|
1085
|
+
#ifdef __AVX2__
|
1062
1086
|
|
1063
1087
|
|
1064
1088
|
template<class Similarity>
|
@@ -1298,7 +1322,7 @@ void ScalarQuantizer::compute_codes (const float * x,
|
|
1298
1322
|
|
1299
1323
|
memset (codes, 0, code_size * n);
|
1300
1324
|
#pragma omp parallel for
|
1301
|
-
for (
|
1325
|
+
for (int64_t i = 0; i < n; i++)
|
1302
1326
|
squant->encode_vector (x + i * d, codes + i * code_size);
|
1303
1327
|
}
|
1304
1328
|
|
@@ -1307,7 +1331,7 @@ void ScalarQuantizer::decode (const uint8_t *codes, float *x, size_t n) const
|
|
1307
1331
|
std::unique_ptr<Quantizer> squant(select_quantizer ());
|
1308
1332
|
|
1309
1333
|
#pragma omp parallel for
|
1310
|
-
for (
|
1334
|
+
for (int64_t i = 0; i < n; i++)
|
1311
1335
|
squant->decode_vector (codes + i * code_size, x + i * d);
|
1312
1336
|
}
|
1313
1337
|
|