faiss 0.1.2 → 0.1.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.
- 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
|
|