faiss 0.2.0 → 0.2.4
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 +16 -0
- data/LICENSE.txt +1 -1
- data/README.md +7 -7
- data/ext/faiss/extconf.rb +6 -3
- data/ext/faiss/numo.hpp +4 -4
- data/ext/faiss/utils.cpp +1 -1
- data/ext/faiss/utils.h +1 -1
- data/lib/faiss/version.rb +1 -1
- data/vendor/faiss/faiss/AutoTune.cpp +292 -291
- data/vendor/faiss/faiss/AutoTune.h +55 -56
- data/vendor/faiss/faiss/Clustering.cpp +365 -194
- data/vendor/faiss/faiss/Clustering.h +102 -35
- data/vendor/faiss/faiss/IVFlib.cpp +171 -195
- data/vendor/faiss/faiss/IVFlib.h +48 -51
- data/vendor/faiss/faiss/Index.cpp +85 -103
- data/vendor/faiss/faiss/Index.h +54 -48
- data/vendor/faiss/faiss/Index2Layer.cpp +126 -224
- data/vendor/faiss/faiss/Index2Layer.h +22 -36
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.cpp +407 -0
- data/vendor/faiss/faiss/IndexAdditiveQuantizer.h +195 -0
- data/vendor/faiss/faiss/IndexBinary.cpp +45 -37
- data/vendor/faiss/faiss/IndexBinary.h +140 -132
- data/vendor/faiss/faiss/IndexBinaryFlat.cpp +73 -53
- data/vendor/faiss/faiss/IndexBinaryFlat.h +29 -24
- data/vendor/faiss/faiss/IndexBinaryFromFloat.cpp +46 -43
- data/vendor/faiss/faiss/IndexBinaryFromFloat.h +16 -15
- data/vendor/faiss/faiss/IndexBinaryHNSW.cpp +215 -232
- data/vendor/faiss/faiss/IndexBinaryHNSW.h +25 -24
- data/vendor/faiss/faiss/IndexBinaryHash.cpp +182 -177
- data/vendor/faiss/faiss/IndexBinaryHash.h +41 -34
- data/vendor/faiss/faiss/IndexBinaryIVF.cpp +489 -461
- data/vendor/faiss/faiss/IndexBinaryIVF.h +97 -68
- data/vendor/faiss/faiss/IndexFlat.cpp +115 -176
- data/vendor/faiss/faiss/IndexFlat.h +42 -59
- data/vendor/faiss/faiss/IndexFlatCodes.cpp +67 -0
- data/vendor/faiss/faiss/IndexFlatCodes.h +47 -0
- data/vendor/faiss/faiss/IndexHNSW.cpp +372 -348
- data/vendor/faiss/faiss/IndexHNSW.h +57 -41
- data/vendor/faiss/faiss/IndexIVF.cpp +545 -453
- data/vendor/faiss/faiss/IndexIVF.h +169 -118
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.cpp +316 -0
- data/vendor/faiss/faiss/IndexIVFAdditiveQuantizer.h +121 -0
- data/vendor/faiss/faiss/IndexIVFFlat.cpp +247 -252
- data/vendor/faiss/faiss/IndexIVFFlat.h +48 -51
- data/vendor/faiss/faiss/IndexIVFPQ.cpp +459 -517
- data/vendor/faiss/faiss/IndexIVFPQ.h +75 -67
- data/vendor/faiss/faiss/IndexIVFPQFastScan.cpp +406 -372
- data/vendor/faiss/faiss/IndexIVFPQFastScan.h +82 -57
- data/vendor/faiss/faiss/IndexIVFPQR.cpp +104 -102
- data/vendor/faiss/faiss/IndexIVFPQR.h +33 -28
- data/vendor/faiss/faiss/IndexIVFSpectralHash.cpp +163 -150
- data/vendor/faiss/faiss/IndexIVFSpectralHash.h +38 -25
- data/vendor/faiss/faiss/IndexLSH.cpp +66 -113
- data/vendor/faiss/faiss/IndexLSH.h +20 -38
- data/vendor/faiss/faiss/IndexLattice.cpp +42 -56
- data/vendor/faiss/faiss/IndexLattice.h +11 -16
- data/vendor/faiss/faiss/IndexNNDescent.cpp +229 -0
- data/vendor/faiss/faiss/IndexNNDescent.h +72 -0
- data/vendor/faiss/faiss/IndexNSG.cpp +301 -0
- data/vendor/faiss/faiss/IndexNSG.h +85 -0
- data/vendor/faiss/faiss/IndexPQ.cpp +387 -495
- data/vendor/faiss/faiss/IndexPQ.h +64 -82
- data/vendor/faiss/faiss/IndexPQFastScan.cpp +143 -170
- data/vendor/faiss/faiss/IndexPQFastScan.h +46 -32
- data/vendor/faiss/faiss/IndexPreTransform.cpp +120 -150
- data/vendor/faiss/faiss/IndexPreTransform.h +33 -36
- data/vendor/faiss/faiss/IndexRefine.cpp +139 -127
- data/vendor/faiss/faiss/IndexRefine.h +32 -23
- data/vendor/faiss/faiss/IndexReplicas.cpp +147 -153
- data/vendor/faiss/faiss/IndexReplicas.h +62 -56
- data/vendor/faiss/faiss/IndexScalarQuantizer.cpp +111 -172
- data/vendor/faiss/faiss/IndexScalarQuantizer.h +41 -59
- data/vendor/faiss/faiss/IndexShards.cpp +256 -240
- data/vendor/faiss/faiss/IndexShards.h +85 -73
- data/vendor/faiss/faiss/MatrixStats.cpp +112 -97
- data/vendor/faiss/faiss/MatrixStats.h +7 -10
- data/vendor/faiss/faiss/MetaIndexes.cpp +135 -157
- data/vendor/faiss/faiss/MetaIndexes.h +40 -34
- data/vendor/faiss/faiss/MetricType.h +7 -7
- data/vendor/faiss/faiss/VectorTransform.cpp +654 -475
- data/vendor/faiss/faiss/VectorTransform.h +64 -89
- data/vendor/faiss/faiss/clone_index.cpp +78 -73
- data/vendor/faiss/faiss/clone_index.h +4 -9
- data/vendor/faiss/faiss/gpu/GpuAutoTune.cpp +33 -38
- data/vendor/faiss/faiss/gpu/GpuAutoTune.h +11 -9
- data/vendor/faiss/faiss/gpu/GpuCloner.cpp +198 -171
- data/vendor/faiss/faiss/gpu/GpuCloner.h +53 -35
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.cpp +12 -14
- data/vendor/faiss/faiss/gpu/GpuClonerOptions.h +27 -25
- data/vendor/faiss/faiss/gpu/GpuDistance.h +116 -112
- data/vendor/faiss/faiss/gpu/GpuFaissAssert.h +1 -2
- data/vendor/faiss/faiss/gpu/GpuIcmEncoder.h +60 -0
- data/vendor/faiss/faiss/gpu/GpuIndex.h +134 -137
- data/vendor/faiss/faiss/gpu/GpuIndexBinaryFlat.h +76 -73
- data/vendor/faiss/faiss/gpu/GpuIndexFlat.h +173 -162
- data/vendor/faiss/faiss/gpu/GpuIndexIVF.h +67 -64
- data/vendor/faiss/faiss/gpu/GpuIndexIVFFlat.h +89 -86
- data/vendor/faiss/faiss/gpu/GpuIndexIVFPQ.h +150 -141
- data/vendor/faiss/faiss/gpu/GpuIndexIVFScalarQuantizer.h +101 -103
- data/vendor/faiss/faiss/gpu/GpuIndicesOptions.h +17 -16
- data/vendor/faiss/faiss/gpu/GpuResources.cpp +116 -128
- data/vendor/faiss/faiss/gpu/GpuResources.h +182 -186
- data/vendor/faiss/faiss/gpu/StandardGpuResources.cpp +433 -422
- data/vendor/faiss/faiss/gpu/StandardGpuResources.h +131 -130
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.cpp +468 -456
- data/vendor/faiss/faiss/gpu/impl/InterleavedCodes.h +25 -19
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.cpp +22 -20
- data/vendor/faiss/faiss/gpu/impl/RemapIndices.h +9 -8
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper-inl.h +39 -44
- data/vendor/faiss/faiss/gpu/perf/IndexWrapper.h +16 -14
- data/vendor/faiss/faiss/gpu/perf/PerfClustering.cpp +77 -71
- data/vendor/faiss/faiss/gpu/perf/PerfIVFPQAdd.cpp +109 -88
- data/vendor/faiss/faiss/gpu/perf/WriteIndex.cpp +75 -64
- data/vendor/faiss/faiss/gpu/test/TestCodePacking.cpp +230 -215
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexBinaryFlat.cpp +80 -86
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexFlat.cpp +284 -277
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFFlat.cpp +416 -416
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFPQ.cpp +611 -517
- data/vendor/faiss/faiss/gpu/test/TestGpuIndexIVFScalarQuantizer.cpp +166 -164
- data/vendor/faiss/faiss/gpu/test/TestGpuMemoryException.cpp +61 -53
- data/vendor/faiss/faiss/gpu/test/TestUtils.cpp +274 -238
- data/vendor/faiss/faiss/gpu/test/TestUtils.h +73 -57
- data/vendor/faiss/faiss/gpu/test/demo_ivfpq_indexing_gpu.cpp +47 -50
- data/vendor/faiss/faiss/gpu/utils/DeviceUtils.h +79 -72
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.cpp +140 -146
- data/vendor/faiss/faiss/gpu/utils/StackDeviceMemory.h +69 -71
- data/vendor/faiss/faiss/gpu/utils/StaticUtils.h +21 -16
- data/vendor/faiss/faiss/gpu/utils/Timer.cpp +25 -29
- data/vendor/faiss/faiss/gpu/utils/Timer.h +30 -29
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.cpp +503 -0
- data/vendor/faiss/faiss/impl/AdditiveQuantizer.h +175 -0
- data/vendor/faiss/faiss/impl/AuxIndexStructures.cpp +90 -120
- data/vendor/faiss/faiss/impl/AuxIndexStructures.h +81 -65
- data/vendor/faiss/faiss/impl/FaissAssert.h +73 -58
- data/vendor/faiss/faiss/impl/FaissException.cpp +56 -48
- data/vendor/faiss/faiss/impl/FaissException.h +41 -29
- data/vendor/faiss/faiss/impl/HNSW.cpp +606 -617
- data/vendor/faiss/faiss/impl/HNSW.h +179 -200
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.cpp +855 -0
- data/vendor/faiss/faiss/impl/LocalSearchQuantizer.h +244 -0
- data/vendor/faiss/faiss/impl/NNDescent.cpp +487 -0
- data/vendor/faiss/faiss/impl/NNDescent.h +154 -0
- data/vendor/faiss/faiss/impl/NSG.cpp +679 -0
- data/vendor/faiss/faiss/impl/NSG.h +199 -0
- data/vendor/faiss/faiss/impl/PolysemousTraining.cpp +484 -454
- data/vendor/faiss/faiss/impl/PolysemousTraining.h +52 -55
- data/vendor/faiss/faiss/impl/ProductQuantizer-inl.h +26 -47
- data/vendor/faiss/faiss/impl/ProductQuantizer.cpp +469 -459
- data/vendor/faiss/faiss/impl/ProductQuantizer.h +76 -87
- data/vendor/faiss/faiss/impl/ResidualQuantizer.cpp +758 -0
- data/vendor/faiss/faiss/impl/ResidualQuantizer.h +188 -0
- data/vendor/faiss/faiss/impl/ResultHandler.h +96 -132
- data/vendor/faiss/faiss/impl/ScalarQuantizer.cpp +647 -707
- data/vendor/faiss/faiss/impl/ScalarQuantizer.h +48 -46
- data/vendor/faiss/faiss/impl/ThreadedIndex-inl.h +129 -131
- data/vendor/faiss/faiss/impl/ThreadedIndex.h +61 -55
- data/vendor/faiss/faiss/impl/index_read.cpp +631 -480
- data/vendor/faiss/faiss/impl/index_write.cpp +547 -407
- data/vendor/faiss/faiss/impl/io.cpp +76 -95
- data/vendor/faiss/faiss/impl/io.h +31 -41
- data/vendor/faiss/faiss/impl/io_macros.h +60 -29
- data/vendor/faiss/faiss/impl/kmeans1d.cpp +301 -0
- data/vendor/faiss/faiss/impl/kmeans1d.h +48 -0
- data/vendor/faiss/faiss/impl/lattice_Zn.cpp +137 -186
- data/vendor/faiss/faiss/impl/lattice_Zn.h +40 -51
- data/vendor/faiss/faiss/impl/platform_macros.h +29 -8
- data/vendor/faiss/faiss/impl/pq4_fast_scan.cpp +77 -124
- data/vendor/faiss/faiss/impl/pq4_fast_scan.h +39 -48
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_1.cpp +41 -52
- data/vendor/faiss/faiss/impl/pq4_fast_scan_search_qbs.cpp +80 -117
- data/vendor/faiss/faiss/impl/simd_result_handlers.h +109 -137
- data/vendor/faiss/faiss/index_factory.cpp +619 -397
- data/vendor/faiss/faiss/index_factory.h +8 -6
- data/vendor/faiss/faiss/index_io.h +23 -26
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.cpp +67 -75
- data/vendor/faiss/faiss/invlists/BlockInvertedLists.h +22 -24
- data/vendor/faiss/faiss/invlists/DirectMap.cpp +96 -112
- data/vendor/faiss/faiss/invlists/DirectMap.h +29 -33
- data/vendor/faiss/faiss/invlists/InvertedLists.cpp +307 -364
- data/vendor/faiss/faiss/invlists/InvertedLists.h +151 -151
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.cpp +29 -34
- data/vendor/faiss/faiss/invlists/InvertedListsIOHook.h +17 -18
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.cpp +257 -293
- data/vendor/faiss/faiss/invlists/OnDiskInvertedLists.h +50 -45
- data/vendor/faiss/faiss/python/python_callbacks.cpp +23 -26
- data/vendor/faiss/faiss/python/python_callbacks.h +9 -16
- data/vendor/faiss/faiss/utils/AlignedTable.h +79 -44
- data/vendor/faiss/faiss/utils/Heap.cpp +40 -48
- data/vendor/faiss/faiss/utils/Heap.h +186 -209
- data/vendor/faiss/faiss/utils/WorkerThread.cpp +67 -76
- data/vendor/faiss/faiss/utils/WorkerThread.h +32 -33
- data/vendor/faiss/faiss/utils/distances.cpp +305 -312
- data/vendor/faiss/faiss/utils/distances.h +170 -122
- data/vendor/faiss/faiss/utils/distances_simd.cpp +498 -508
- data/vendor/faiss/faiss/utils/extra_distances-inl.h +117 -0
- data/vendor/faiss/faiss/utils/extra_distances.cpp +113 -232
- data/vendor/faiss/faiss/utils/extra_distances.h +30 -29
- data/vendor/faiss/faiss/utils/hamming-inl.h +260 -209
- data/vendor/faiss/faiss/utils/hamming.cpp +375 -469
- data/vendor/faiss/faiss/utils/hamming.h +62 -85
- data/vendor/faiss/faiss/utils/ordered_key_value.h +16 -18
- data/vendor/faiss/faiss/utils/partitioning.cpp +393 -318
- data/vendor/faiss/faiss/utils/partitioning.h +26 -21
- data/vendor/faiss/faiss/utils/quantize_lut.cpp +78 -66
- data/vendor/faiss/faiss/utils/quantize_lut.h +22 -20
- data/vendor/faiss/faiss/utils/random.cpp +39 -63
- data/vendor/faiss/faiss/utils/random.h +13 -16
- data/vendor/faiss/faiss/utils/simdlib.h +4 -2
- data/vendor/faiss/faiss/utils/simdlib_avx2.h +88 -85
- data/vendor/faiss/faiss/utils/simdlib_emulated.h +226 -165
- data/vendor/faiss/faiss/utils/simdlib_neon.h +832 -0
- data/vendor/faiss/faiss/utils/utils.cpp +304 -287
- data/vendor/faiss/faiss/utils/utils.h +54 -49
- metadata +29 -4
|
@@ -22,200 +22,164 @@
|
|
|
22
22
|
*
|
|
23
23
|
* The hamdis_t should optimally be compatibe with one of the Torch Storage
|
|
24
24
|
* (Byte,Short,Long) and therefore should be signed for 2-bytes and 4-bytes
|
|
25
|
-
*/
|
|
25
|
+
*/
|
|
26
26
|
|
|
27
27
|
#include <faiss/utils/hamming.h>
|
|
28
28
|
|
|
29
|
+
#include <math.h>
|
|
30
|
+
#include <stdio.h>
|
|
29
31
|
#include <algorithm>
|
|
30
|
-
#include <vector>
|
|
31
32
|
#include <memory>
|
|
32
|
-
#include <
|
|
33
|
-
#include <math.h>
|
|
33
|
+
#include <vector>
|
|
34
34
|
|
|
35
|
-
#include <faiss/
|
|
35
|
+
#include <faiss/impl/AuxIndexStructures.h>
|
|
36
36
|
#include <faiss/impl/FaissAssert.h>
|
|
37
|
+
#include <faiss/utils/Heap.h>
|
|
37
38
|
#include <faiss/utils/utils.h>
|
|
38
|
-
#include <faiss/impl/AuxIndexStructures.h>
|
|
39
39
|
|
|
40
40
|
static const size_t BLOCKSIZE_QUERY = 8192;
|
|
41
41
|
|
|
42
|
-
|
|
43
42
|
namespace faiss {
|
|
44
43
|
|
|
45
44
|
size_t hamming_batch_size = 65536;
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
60
|
-
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
61
|
-
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
62
|
-
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
63
|
-
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
|
|
64
|
-
};
|
|
65
|
-
|
|
46
|
+
const uint8_t hamdis_tab_ham_bytes[256] = {
|
|
47
|
+
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
|
|
48
|
+
2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
49
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
|
|
50
|
+
2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
51
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
52
|
+
4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
53
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
54
|
+
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
55
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
56
|
+
4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
57
|
+
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
|
|
66
58
|
|
|
67
59
|
/* Elementary Hamming distance computation: unoptimized */
|
|
68
60
|
template <size_t nbits, typename T>
|
|
69
|
-
T hamming
|
|
70
|
-
const uint8_t *bs2)
|
|
71
|
-
{
|
|
61
|
+
T hamming(const uint8_t* bs1, const uint8_t* bs2) {
|
|
72
62
|
const size_t nbytes = nbits / 8;
|
|
73
63
|
size_t i;
|
|
74
64
|
T h = 0;
|
|
75
65
|
for (i = 0; i < nbytes; i++)
|
|
76
|
-
h += (T)
|
|
66
|
+
h += (T)hamdis_tab_ham_bytes[bs1[i] ^ bs2[i]];
|
|
77
67
|
return h;
|
|
78
68
|
}
|
|
79
69
|
|
|
80
|
-
|
|
81
70
|
/* Hamming distances for multiples of 64 bits */
|
|
82
71
|
template <size_t nbits>
|
|
83
|
-
hamdis_t hamming
|
|
84
|
-
{
|
|
72
|
+
hamdis_t hamming(const uint64_t* bs1, const uint64_t* bs2) {
|
|
85
73
|
const size_t nwords = nbits / 64;
|
|
86
74
|
size_t i;
|
|
87
75
|
hamdis_t h = 0;
|
|
88
76
|
for (i = 0; i < nwords; i++)
|
|
89
|
-
h += popcount64
|
|
77
|
+
h += popcount64(bs1[i] ^ bs2[i]);
|
|
90
78
|
return h;
|
|
91
79
|
}
|
|
92
80
|
|
|
93
|
-
|
|
94
|
-
|
|
95
81
|
/* specialized (optimized) functions */
|
|
96
82
|
template <>
|
|
97
|
-
hamdis_t hamming<64>
|
|
98
|
-
|
|
99
|
-
return popcount64 (pa[0] ^ pb[0]);
|
|
83
|
+
hamdis_t hamming<64>(const uint64_t* pa, const uint64_t* pb) {
|
|
84
|
+
return popcount64(pa[0] ^ pb[0]);
|
|
100
85
|
}
|
|
101
86
|
|
|
102
|
-
|
|
103
87
|
template <>
|
|
104
|
-
hamdis_t hamming<128>
|
|
105
|
-
|
|
106
|
-
return popcount64 (pa[0] ^ pb[0]) + popcount64(pa[1] ^ pb[1]);
|
|
88
|
+
hamdis_t hamming<128>(const uint64_t* pa, const uint64_t* pb) {
|
|
89
|
+
return popcount64(pa[0] ^ pb[0]) + popcount64(pa[1] ^ pb[1]);
|
|
107
90
|
}
|
|
108
91
|
|
|
109
|
-
|
|
110
92
|
template <>
|
|
111
|
-
hamdis_t hamming<256>
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
+ popcount64 (pa[1] ^ pb[1])
|
|
115
|
-
+ popcount64 (pa[2] ^ pb[2])
|
|
116
|
-
+ popcount64 (pa[3] ^ pb[3]);
|
|
93
|
+
hamdis_t hamming<256>(const uint64_t* pa, const uint64_t* pb) {
|
|
94
|
+
return popcount64(pa[0] ^ pb[0]) + popcount64(pa[1] ^ pb[1]) +
|
|
95
|
+
popcount64(pa[2] ^ pb[2]) + popcount64(pa[3] ^ pb[3]);
|
|
117
96
|
}
|
|
118
97
|
|
|
119
|
-
|
|
120
98
|
/* Hamming distances for multiple of 64 bits */
|
|
121
|
-
hamdis_t hamming
|
|
122
|
-
const uint64_t * bs1,
|
|
123
|
-
const uint64_t * bs2,
|
|
124
|
-
size_t nwords)
|
|
125
|
-
{
|
|
99
|
+
hamdis_t hamming(const uint64_t* bs1, const uint64_t* bs2, size_t nwords) {
|
|
126
100
|
size_t i;
|
|
127
101
|
hamdis_t h = 0;
|
|
128
102
|
for (i = 0; i < nwords; i++)
|
|
129
|
-
h += popcount64
|
|
103
|
+
h += popcount64(bs1[i] ^ bs2[i]);
|
|
130
104
|
return h;
|
|
131
105
|
}
|
|
132
106
|
|
|
133
|
-
|
|
134
|
-
|
|
135
107
|
template <size_t nbits>
|
|
136
|
-
void hammings
|
|
137
|
-
const uint64_t
|
|
138
|
-
const uint64_t
|
|
139
|
-
size_t n1,
|
|
140
|
-
|
|
108
|
+
void hammings(
|
|
109
|
+
const uint64_t* bs1,
|
|
110
|
+
const uint64_t* bs2,
|
|
111
|
+
size_t n1,
|
|
112
|
+
size_t n2,
|
|
113
|
+
hamdis_t* dis)
|
|
141
114
|
|
|
142
115
|
{
|
|
143
116
|
size_t i, j;
|
|
144
117
|
const size_t nwords = nbits / 64;
|
|
145
118
|
for (i = 0; i < n1; i++) {
|
|
146
|
-
const uint64_t
|
|
147
|
-
hamdis_t
|
|
119
|
+
const uint64_t* __restrict bs1_ = bs1 + i * nwords;
|
|
120
|
+
hamdis_t* __restrict dis_ = dis + i * n2;
|
|
148
121
|
for (j = 0; j < n2; j++)
|
|
149
122
|
dis_[j] = hamming<nbits>(bs1_, bs2 + j * nwords);
|
|
150
123
|
}
|
|
151
124
|
}
|
|
152
125
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const uint64_t * bs1,
|
|
157
|
-
const uint64_t * bs2,
|
|
126
|
+
void hammings(
|
|
127
|
+
const uint64_t* bs1,
|
|
128
|
+
const uint64_t* bs2,
|
|
158
129
|
size_t n1,
|
|
159
130
|
size_t n2,
|
|
160
131
|
size_t nwords,
|
|
161
|
-
hamdis_t
|
|
162
|
-
{
|
|
132
|
+
hamdis_t* __restrict dis) {
|
|
163
133
|
size_t i, j;
|
|
164
134
|
n1 *= nwords;
|
|
165
135
|
n2 *= nwords;
|
|
166
|
-
for (i = 0; i < n1; i+=nwords) {
|
|
167
|
-
const uint64_t
|
|
168
|
-
for (j = 0; j < n2; j+=nwords)
|
|
169
|
-
dis[j] = hamming
|
|
136
|
+
for (i = 0; i < n1; i += nwords) {
|
|
137
|
+
const uint64_t* bs1_ = bs1 + i;
|
|
138
|
+
for (j = 0; j < n2; j += nwords)
|
|
139
|
+
dis[j] = hamming(bs1_, bs2 + j, nwords);
|
|
170
140
|
}
|
|
171
141
|
}
|
|
172
142
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
143
|
/* Count number of matches given a max threshold */
|
|
177
144
|
template <size_t nbits>
|
|
178
|
-
void hamming_count_thres
|
|
179
|
-
const uint64_t
|
|
180
|
-
const uint64_t
|
|
145
|
+
void hamming_count_thres(
|
|
146
|
+
const uint64_t* bs1,
|
|
147
|
+
const uint64_t* bs2,
|
|
181
148
|
size_t n1,
|
|
182
149
|
size_t n2,
|
|
183
150
|
hamdis_t ht,
|
|
184
|
-
size_t
|
|
185
|
-
{
|
|
151
|
+
size_t* nptr) {
|
|
186
152
|
const size_t nwords = nbits / 64;
|
|
187
153
|
size_t i, j, posm = 0;
|
|
188
|
-
const uint64_t
|
|
154
|
+
const uint64_t* bs2_ = bs2;
|
|
189
155
|
|
|
190
156
|
for (i = 0; i < n1; i++) {
|
|
191
157
|
bs2 = bs2_;
|
|
192
158
|
for (j = 0; j < n2; j++) {
|
|
193
159
|
/* collect the match only if this satisfies the threshold */
|
|
194
|
-
if (hamming
|
|
160
|
+
if (hamming<nbits>(bs1, bs2) <= ht)
|
|
195
161
|
posm++;
|
|
196
162
|
bs2 += nwords;
|
|
197
163
|
}
|
|
198
|
-
bs1 += nwords;
|
|
164
|
+
bs1 += nwords; /* next signature */
|
|
199
165
|
}
|
|
200
166
|
*nptr = posm;
|
|
201
167
|
}
|
|
202
168
|
|
|
203
|
-
|
|
204
169
|
template <size_t nbits>
|
|
205
|
-
void crosshamming_count_thres
|
|
206
|
-
const uint64_t
|
|
170
|
+
void crosshamming_count_thres(
|
|
171
|
+
const uint64_t* dbs,
|
|
207
172
|
size_t n,
|
|
208
173
|
int ht,
|
|
209
|
-
size_t
|
|
210
|
-
{
|
|
174
|
+
size_t* nptr) {
|
|
211
175
|
const size_t nwords = nbits / 64;
|
|
212
176
|
size_t i, j, posm = 0;
|
|
213
|
-
const uint64_t
|
|
177
|
+
const uint64_t* bs1 = dbs;
|
|
214
178
|
for (i = 0; i < n; i++) {
|
|
215
|
-
const uint64_t
|
|
179
|
+
const uint64_t* bs2 = bs1 + 2;
|
|
216
180
|
for (j = i + 1; j < n; j++) {
|
|
217
181
|
/* collect the match only if this satisfies the threshold */
|
|
218
|
-
if (hamming
|
|
182
|
+
if (hamming<nbits>(bs1, bs2) <= ht)
|
|
219
183
|
posm++;
|
|
220
184
|
bs2 += nwords;
|
|
221
185
|
}
|
|
@@ -224,185 +188,175 @@ void crosshamming_count_thres (
|
|
|
224
188
|
*nptr = posm;
|
|
225
189
|
}
|
|
226
190
|
|
|
227
|
-
|
|
228
191
|
template <size_t nbits>
|
|
229
|
-
size_t match_hamming_thres
|
|
230
|
-
const uint64_t
|
|
231
|
-
const uint64_t
|
|
192
|
+
size_t match_hamming_thres(
|
|
193
|
+
const uint64_t* bs1,
|
|
194
|
+
const uint64_t* bs2,
|
|
232
195
|
size_t n1,
|
|
233
196
|
size_t n2,
|
|
234
197
|
int ht,
|
|
235
|
-
int64_t
|
|
236
|
-
hamdis_t
|
|
237
|
-
{
|
|
198
|
+
int64_t* idx,
|
|
199
|
+
hamdis_t* hams) {
|
|
238
200
|
const size_t nwords = nbits / 64;
|
|
239
201
|
size_t i, j, posm = 0;
|
|
240
202
|
hamdis_t h;
|
|
241
|
-
const uint64_t
|
|
203
|
+
const uint64_t* bs2_ = bs2;
|
|
242
204
|
for (i = 0; i < n1; i++) {
|
|
243
205
|
bs2 = bs2_;
|
|
244
206
|
for (j = 0; j < n2; j++) {
|
|
245
207
|
/* Here perform the real work of computing the distance */
|
|
246
|
-
h = hamming
|
|
208
|
+
h = hamming<nbits>(bs1, bs2);
|
|
247
209
|
|
|
248
210
|
/* collect the match only if this satisfies the threshold */
|
|
249
211
|
if (h <= ht) {
|
|
250
212
|
/* Enough space to store another match ? */
|
|
251
|
-
*idx = i;
|
|
252
|
-
|
|
213
|
+
*idx = i;
|
|
214
|
+
idx++;
|
|
215
|
+
*idx = j;
|
|
216
|
+
idx++;
|
|
253
217
|
*hams = h;
|
|
254
218
|
hams++;
|
|
255
219
|
posm++;
|
|
256
220
|
}
|
|
257
|
-
bs2+=nwords;
|
|
221
|
+
bs2 += nwords; /* next signature */
|
|
258
222
|
}
|
|
259
|
-
bs1+=nwords;
|
|
223
|
+
bs1 += nwords;
|
|
260
224
|
}
|
|
261
225
|
return posm;
|
|
262
226
|
}
|
|
263
227
|
|
|
264
|
-
|
|
265
228
|
/* Return closest neighbors w.r.t Hamming distance, using a heap. */
|
|
266
229
|
template <class HammingComputer>
|
|
267
|
-
static
|
|
268
|
-
void hammings_knn_hc (
|
|
230
|
+
static void hammings_knn_hc(
|
|
269
231
|
int bytes_per_code,
|
|
270
|
-
int_maxheap_array_t
|
|
271
|
-
const uint8_t
|
|
272
|
-
const uint8_t
|
|
232
|
+
int_maxheap_array_t* ha,
|
|
233
|
+
const uint8_t* bs1,
|
|
234
|
+
const uint8_t* bs2,
|
|
273
235
|
size_t n2,
|
|
274
236
|
bool order = true,
|
|
275
|
-
bool init_heap = true)
|
|
276
|
-
{
|
|
237
|
+
bool init_heap = true) {
|
|
277
238
|
size_t k = ha->k;
|
|
278
|
-
if (init_heap)
|
|
239
|
+
if (init_heap)
|
|
240
|
+
ha->heapify();
|
|
279
241
|
|
|
280
242
|
const size_t block_size = hamming_batch_size;
|
|
281
243
|
for (size_t j0 = 0; j0 < n2; j0 += block_size) {
|
|
282
|
-
|
|
244
|
+
const size_t j1 = std::min(j0 + block_size, n2);
|
|
283
245
|
#pragma omp parallel for
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
246
|
+
for (int64_t i = 0; i < ha->nh; i++) {
|
|
247
|
+
HammingComputer hc(bs1 + i * bytes_per_code, bytes_per_code);
|
|
248
|
+
|
|
249
|
+
const uint8_t* bs2_ = bs2 + j0 * bytes_per_code;
|
|
250
|
+
hamdis_t dis;
|
|
251
|
+
hamdis_t* __restrict bh_val_ = ha->val + i * k;
|
|
252
|
+
int64_t* __restrict bh_ids_ = ha->ids + i * k;
|
|
253
|
+
size_t j;
|
|
254
|
+
for (j = j0; j < j1; j++, bs2_ += bytes_per_code) {
|
|
255
|
+
dis = hc.hamming(bs2_);
|
|
256
|
+
if (dis < bh_val_[0]) {
|
|
257
|
+
faiss::maxheap_replace_top<hamdis_t>(
|
|
258
|
+
k, bh_val_, bh_ids_, dis, j);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
297
261
|
}
|
|
298
|
-
}
|
|
299
262
|
}
|
|
300
|
-
if (order)
|
|
301
|
-
|
|
263
|
+
if (order)
|
|
264
|
+
ha->reorder();
|
|
265
|
+
}
|
|
302
266
|
|
|
303
267
|
/* Return closest neighbors w.r.t Hamming distance, using max count. */
|
|
304
268
|
template <class HammingComputer>
|
|
305
|
-
static
|
|
306
|
-
void hammings_knn_mc (
|
|
269
|
+
static void hammings_knn_mc(
|
|
307
270
|
int bytes_per_code,
|
|
308
|
-
const uint8_t
|
|
309
|
-
const uint8_t
|
|
271
|
+
const uint8_t* a,
|
|
272
|
+
const uint8_t* b,
|
|
310
273
|
size_t na,
|
|
311
274
|
size_t nb,
|
|
312
275
|
size_t k,
|
|
313
|
-
int32_t
|
|
314
|
-
int64_t
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
k
|
|
328
|
-
));
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
const size_t block_size = hamming_batch_size;
|
|
332
|
-
for (size_t j0 = 0; j0 < nb; j0 += block_size) {
|
|
333
|
-
const size_t j1 = std::min(j0 + block_size, nb);
|
|
334
|
-
#pragma omp parallel for
|
|
335
|
-
for (int64_t i = 0; i < na; ++i) {
|
|
336
|
-
for (size_t j = j0; j < j1; ++j) {
|
|
337
|
-
cs[i].update_counter(b + j * bytes_per_code, j);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
for (size_t i = 0; i < na; ++i) {
|
|
343
|
-
HCounterState<HammingComputer>& csi = cs[i];
|
|
344
|
-
|
|
345
|
-
int nres = 0;
|
|
346
|
-
for (int b = 0; b < nBuckets && nres < k; b++) {
|
|
347
|
-
for (int l = 0; l < csi.counters[b] && nres < k; l++) {
|
|
348
|
-
labels[i * k + nres] = csi.ids_per_dis[b * k + l];
|
|
349
|
-
distances[i * k + nres] = b;
|
|
350
|
-
nres++;
|
|
351
|
-
}
|
|
276
|
+
int32_t* distances,
|
|
277
|
+
int64_t* labels) {
|
|
278
|
+
const int nBuckets = bytes_per_code * 8 + 1;
|
|
279
|
+
std::vector<int> all_counters(na * nBuckets, 0);
|
|
280
|
+
std::unique_ptr<int64_t[]> all_ids_per_dis(new int64_t[na * nBuckets * k]);
|
|
281
|
+
|
|
282
|
+
std::vector<HCounterState<HammingComputer>> cs;
|
|
283
|
+
for (size_t i = 0; i < na; ++i) {
|
|
284
|
+
cs.push_back(HCounterState<HammingComputer>(
|
|
285
|
+
all_counters.data() + i * nBuckets,
|
|
286
|
+
all_ids_per_dis.get() + i * nBuckets * k,
|
|
287
|
+
a + i * bytes_per_code,
|
|
288
|
+
8 * bytes_per_code,
|
|
289
|
+
k));
|
|
352
290
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
291
|
+
|
|
292
|
+
const size_t block_size = hamming_batch_size;
|
|
293
|
+
for (size_t j0 = 0; j0 < nb; j0 += block_size) {
|
|
294
|
+
const size_t j1 = std::min(j0 + block_size, nb);
|
|
295
|
+
#pragma omp parallel for
|
|
296
|
+
for (int64_t i = 0; i < na; ++i) {
|
|
297
|
+
for (size_t j = j0; j < j1; ++j) {
|
|
298
|
+
cs[i].update_counter(b + j * bytes_per_code, j);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
357
301
|
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
302
|
|
|
303
|
+
for (size_t i = 0; i < na; ++i) {
|
|
304
|
+
HCounterState<HammingComputer>& csi = cs[i];
|
|
361
305
|
|
|
306
|
+
int nres = 0;
|
|
307
|
+
for (int b = 0; b < nBuckets && nres < k; b++) {
|
|
308
|
+
for (int l = 0; l < csi.counters[b] && nres < k; l++) {
|
|
309
|
+
labels[i * k + nres] = csi.ids_per_dis[b * k + l];
|
|
310
|
+
distances[i * k + nres] = b;
|
|
311
|
+
nres++;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
while (nres < k) {
|
|
315
|
+
labels[i * k + nres] = -1;
|
|
316
|
+
distances[i * k + nres] = std::numeric_limits<int32_t>::max();
|
|
317
|
+
++nres;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
362
321
|
|
|
363
322
|
// works faster than the template version
|
|
364
|
-
static
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const uint64_t
|
|
368
|
-
const uint64_t * bs2,
|
|
323
|
+
static void hammings_knn_hc_1(
|
|
324
|
+
int_maxheap_array_t* ha,
|
|
325
|
+
const uint64_t* bs1,
|
|
326
|
+
const uint64_t* bs2,
|
|
369
327
|
size_t n2,
|
|
370
328
|
bool order = true,
|
|
371
|
-
bool init_heap = true)
|
|
372
|
-
{
|
|
329
|
+
bool init_heap = true) {
|
|
373
330
|
const size_t nwords = 1;
|
|
374
331
|
size_t k = ha->k;
|
|
375
332
|
|
|
376
|
-
|
|
377
333
|
if (init_heap) {
|
|
378
|
-
ha->heapify
|
|
334
|
+
ha->heapify();
|
|
379
335
|
}
|
|
380
336
|
|
|
381
337
|
#pragma omp parallel for
|
|
382
338
|
for (int64_t i = 0; i < ha->nh; i++) {
|
|
383
|
-
const uint64_t bs1_ = bs1
|
|
384
|
-
const uint64_t
|
|
339
|
+
const uint64_t bs1_ = bs1[i];
|
|
340
|
+
const uint64_t* bs2_ = bs2;
|
|
385
341
|
hamdis_t dis;
|
|
386
|
-
hamdis_t
|
|
342
|
+
hamdis_t* bh_val_ = ha->val + i * k;
|
|
387
343
|
hamdis_t bh_val_0 = bh_val_[0];
|
|
388
|
-
int64_t
|
|
344
|
+
int64_t* bh_ids_ = ha->ids + i * k;
|
|
389
345
|
size_t j;
|
|
390
|
-
for (j = 0; j < n2; j++, bs2_+= nwords) {
|
|
391
|
-
dis = popcount64
|
|
346
|
+
for (j = 0; j < n2; j++, bs2_ += nwords) {
|
|
347
|
+
dis = popcount64(bs1_ ^ *bs2_);
|
|
392
348
|
if (dis < bh_val_0) {
|
|
393
|
-
faiss::maxheap_replace_top<hamdis_t>
|
|
349
|
+
faiss::maxheap_replace_top<hamdis_t>(
|
|
350
|
+
k, bh_val_, bh_ids_, dis, j);
|
|
394
351
|
bh_val_0 = bh_val_[0];
|
|
395
352
|
}
|
|
396
353
|
}
|
|
397
354
|
}
|
|
398
355
|
if (order) {
|
|
399
|
-
ha->reorder
|
|
356
|
+
ha->reorder();
|
|
400
357
|
}
|
|
401
358
|
}
|
|
402
359
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
360
|
/* Functions to maps vectors to bits. Assume proper allocation done beforehand,
|
|
407
361
|
meaning that b should be be able to receive as many bits as x may produce. */
|
|
408
362
|
|
|
@@ -410,8 +364,7 @@ void hammings_knn_hc_1 (
|
|
|
410
364
|
* dimension 0 corresponds to the least significant bit of b[0], or
|
|
411
365
|
* equivalently to the lsb of the first byte that is stored.
|
|
412
366
|
*/
|
|
413
|
-
void fvec2bitvec
|
|
414
|
-
{
|
|
367
|
+
void fvec2bitvec(const float* x, uint8_t* b, size_t d) {
|
|
415
368
|
for (int i = 0; i < d; i += 8) {
|
|
416
369
|
uint8_t w = 0;
|
|
417
370
|
uint8_t mask = 1;
|
|
@@ -426,37 +379,25 @@ void fvec2bitvec (const float * x, uint8_t * b, size_t d)
|
|
|
426
379
|
}
|
|
427
380
|
}
|
|
428
381
|
|
|
429
|
-
|
|
430
|
-
|
|
431
382
|
/* Same but for n vectors.
|
|
432
383
|
Ensure that the ouptut b is byte-aligned (pad with 0s). */
|
|
433
|
-
void fvecs2bitvecs
|
|
434
|
-
{
|
|
384
|
+
void fvecs2bitvecs(const float* x, uint8_t* b, size_t d, size_t n) {
|
|
435
385
|
const int64_t ncodes = ((d + 7) / 8);
|
|
436
|
-
#pragma omp parallel for if(n > 100000)
|
|
386
|
+
#pragma omp parallel for if (n > 100000)
|
|
437
387
|
for (int64_t i = 0; i < n; i++)
|
|
438
|
-
fvec2bitvec
|
|
388
|
+
fvec2bitvec(x + i * d, b + i * ncodes, d);
|
|
439
389
|
}
|
|
440
390
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
void bitvecs2fvecs (
|
|
444
|
-
const uint8_t * b,
|
|
445
|
-
float * x,
|
|
446
|
-
size_t d,
|
|
447
|
-
size_t n) {
|
|
448
|
-
|
|
391
|
+
void bitvecs2fvecs(const uint8_t* b, float* x, size_t d, size_t n) {
|
|
449
392
|
const int64_t ncodes = ((d + 7) / 8);
|
|
450
|
-
#pragma omp parallel for if(n > 100000)
|
|
393
|
+
#pragma omp parallel for if (n > 100000)
|
|
451
394
|
for (int64_t i = 0; i < n; i++) {
|
|
452
|
-
binary_to_real
|
|
395
|
+
binary_to_real(d, b + i * ncodes, x + i * d);
|
|
453
396
|
}
|
|
454
397
|
}
|
|
455
398
|
|
|
456
|
-
|
|
457
399
|
/* Reverse bit (NOT a optimized function, only used for print purpose) */
|
|
458
|
-
static uint64_t uint64_reverse_bits
|
|
459
|
-
{
|
|
400
|
+
static uint64_t uint64_reverse_bits(uint64_t b) {
|
|
460
401
|
int i;
|
|
461
402
|
uint64_t revb = 0;
|
|
462
403
|
for (i = 0; i < 64; i++) {
|
|
@@ -467,406 +408,371 @@ static uint64_t uint64_reverse_bits (uint64_t b)
|
|
|
467
408
|
return revb;
|
|
468
409
|
}
|
|
469
410
|
|
|
470
|
-
|
|
471
411
|
/* print the bit vector */
|
|
472
|
-
void bitvec_print
|
|
473
|
-
{
|
|
412
|
+
void bitvec_print(const uint8_t* b, size_t d) {
|
|
474
413
|
size_t i, j;
|
|
475
|
-
for (i = 0; i < d;
|
|
476
|
-
uint64_t brev = uint64_reverse_bits
|
|
414
|
+
for (i = 0; i < d;) {
|
|
415
|
+
uint64_t brev = uint64_reverse_bits(*(uint64_t*)b);
|
|
477
416
|
for (j = 0; j < 64 && i < d; j++, i++) {
|
|
478
|
-
printf
|
|
417
|
+
printf("%d", (int)(brev & 1));
|
|
479
418
|
brev >>= 1;
|
|
480
419
|
}
|
|
481
420
|
b += 8;
|
|
482
|
-
printf
|
|
421
|
+
printf(" ");
|
|
483
422
|
}
|
|
484
423
|
}
|
|
485
424
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
425
|
+
void bitvec_shuffle(
|
|
426
|
+
size_t n,
|
|
427
|
+
size_t da,
|
|
428
|
+
size_t db,
|
|
429
|
+
const int* order,
|
|
430
|
+
const uint8_t* a,
|
|
431
|
+
uint8_t* b) {
|
|
432
|
+
for (size_t i = 0; i < db; i++) {
|
|
433
|
+
FAISS_THROW_IF_NOT(order[i] >= 0 && order[i] < da);
|
|
494
434
|
}
|
|
495
435
|
size_t lda = (da + 7) / 8;
|
|
496
436
|
size_t ldb = (db + 7) / 8;
|
|
497
437
|
|
|
498
|
-
#pragma omp parallel for if(n > 10000)
|
|
438
|
+
#pragma omp parallel for if (n > 10000)
|
|
499
439
|
for (int64_t i = 0; i < n; i++) {
|
|
500
|
-
const uint8_t
|
|
501
|
-
uint8_t
|
|
502
|
-
memset
|
|
503
|
-
for(size_t
|
|
504
|
-
int o = order[
|
|
440
|
+
const uint8_t* ai = a + i * lda;
|
|
441
|
+
uint8_t* bi = b + i * ldb;
|
|
442
|
+
memset(bi, 0, ldb);
|
|
443
|
+
for (size_t j = 0; j < db; j++) {
|
|
444
|
+
int o = order[j];
|
|
505
445
|
uint8_t the_bit = (ai[o >> 3] >> (o & 7)) & 1;
|
|
506
|
-
bi[
|
|
446
|
+
bi[j >> 3] |= the_bit << (j & 7);
|
|
507
447
|
}
|
|
508
448
|
}
|
|
509
|
-
|
|
510
449
|
}
|
|
511
450
|
|
|
512
|
-
|
|
513
|
-
|
|
514
451
|
/*----------------------------------------*/
|
|
515
452
|
/* Hamming distance computation and k-nn */
|
|
516
453
|
|
|
517
|
-
|
|
518
|
-
#define C64(x) ((uint64_t *)x)
|
|
519
|
-
|
|
454
|
+
#define C64(x) ((uint64_t*)x)
|
|
520
455
|
|
|
521
456
|
/* Compute a set of Hamming distances */
|
|
522
|
-
void hammings
|
|
523
|
-
const uint8_t
|
|
524
|
-
const uint8_t
|
|
525
|
-
size_t na,
|
|
457
|
+
void hammings(
|
|
458
|
+
const uint8_t* a,
|
|
459
|
+
const uint8_t* b,
|
|
460
|
+
size_t na,
|
|
461
|
+
size_t nb,
|
|
526
462
|
size_t ncodes,
|
|
527
|
-
hamdis_t
|
|
528
|
-
|
|
529
|
-
FAISS_THROW_IF_NOT (ncodes % 8 == 0);
|
|
463
|
+
hamdis_t* __restrict dis) {
|
|
464
|
+
FAISS_THROW_IF_NOT(ncodes % 8 == 0);
|
|
530
465
|
switch (ncodes) {
|
|
531
466
|
case 8:
|
|
532
|
-
faiss::hammings
|
|
467
|
+
faiss::hammings<64>(C64(a), C64(b), na, nb, dis);
|
|
468
|
+
return;
|
|
533
469
|
case 16:
|
|
534
|
-
faiss::hammings
|
|
470
|
+
faiss::hammings<128>(C64(a), C64(b), na, nb, dis);
|
|
471
|
+
return;
|
|
535
472
|
case 32:
|
|
536
|
-
faiss::hammings
|
|
473
|
+
faiss::hammings<256>(C64(a), C64(b), na, nb, dis);
|
|
474
|
+
return;
|
|
537
475
|
case 64:
|
|
538
|
-
faiss::hammings
|
|
476
|
+
faiss::hammings<512>(C64(a), C64(b), na, nb, dis);
|
|
477
|
+
return;
|
|
539
478
|
default:
|
|
540
|
-
faiss::hammings
|
|
479
|
+
faiss::hammings(C64(a), C64(b), na, nb, ncodes * 8, dis);
|
|
480
|
+
return;
|
|
541
481
|
}
|
|
542
482
|
}
|
|
543
483
|
|
|
544
484
|
void hammings_knn(
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
{
|
|
485
|
+
int_maxheap_array_t* ha,
|
|
486
|
+
const uint8_t* a,
|
|
487
|
+
const uint8_t* b,
|
|
488
|
+
size_t nb,
|
|
489
|
+
size_t ncodes,
|
|
490
|
+
int order) {
|
|
552
491
|
hammings_knn_hc(ha, a, b, nb, ncodes, order);
|
|
553
492
|
}
|
|
554
493
|
|
|
555
|
-
void hammings_knn_hc
|
|
556
|
-
int_maxheap_array_t
|
|
557
|
-
const uint8_t
|
|
558
|
-
const uint8_t
|
|
494
|
+
void hammings_knn_hc(
|
|
495
|
+
int_maxheap_array_t* ha,
|
|
496
|
+
const uint8_t* a,
|
|
497
|
+
const uint8_t* b,
|
|
559
498
|
size_t nb,
|
|
560
499
|
size_t ncodes,
|
|
561
|
-
int order)
|
|
562
|
-
{
|
|
500
|
+
int order) {
|
|
563
501
|
switch (ncodes) {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
} else {
|
|
586
|
-
hammings_knn_hc<faiss::HammingComputerDefault>
|
|
587
|
-
(ncodes, ha, a, b, nb, order, true);
|
|
588
|
-
|
|
589
|
-
}
|
|
502
|
+
case 4:
|
|
503
|
+
hammings_knn_hc<faiss::HammingComputer4>(
|
|
504
|
+
4, ha, a, b, nb, order, true);
|
|
505
|
+
break;
|
|
506
|
+
case 8:
|
|
507
|
+
hammings_knn_hc_1(ha, C64(a), C64(b), nb, order, true);
|
|
508
|
+
// hammings_knn_hc<faiss::HammingComputer8>
|
|
509
|
+
// (8, ha, a, b, nb, order, true);
|
|
510
|
+
break;
|
|
511
|
+
case 16:
|
|
512
|
+
hammings_knn_hc<faiss::HammingComputer16>(
|
|
513
|
+
16, ha, a, b, nb, order, true);
|
|
514
|
+
break;
|
|
515
|
+
case 32:
|
|
516
|
+
hammings_knn_hc<faiss::HammingComputer32>(
|
|
517
|
+
32, ha, a, b, nb, order, true);
|
|
518
|
+
break;
|
|
519
|
+
default:
|
|
520
|
+
hammings_knn_hc<faiss::HammingComputerDefault>(
|
|
521
|
+
ncodes, ha, a, b, nb, order, true);
|
|
522
|
+
break;
|
|
590
523
|
}
|
|
591
524
|
}
|
|
592
525
|
|
|
593
526
|
void hammings_knn_mc(
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
{
|
|
527
|
+
const uint8_t* a,
|
|
528
|
+
const uint8_t* b,
|
|
529
|
+
size_t na,
|
|
530
|
+
size_t nb,
|
|
531
|
+
size_t k,
|
|
532
|
+
size_t ncodes,
|
|
533
|
+
int32_t* distances,
|
|
534
|
+
int64_t* labels) {
|
|
603
535
|
switch (ncodes) {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
32, a, b, na, nb, k, distances, labels
|
|
624
|
-
);
|
|
625
|
-
break;
|
|
626
|
-
default:
|
|
627
|
-
if(ncodes % 8 == 0) {
|
|
628
|
-
hammings_knn_mc<faiss::HammingComputerM8>(
|
|
629
|
-
ncodes, a, b, na, nb, k, distances, labels
|
|
630
|
-
);
|
|
631
|
-
} else {
|
|
536
|
+
case 4:
|
|
537
|
+
hammings_knn_mc<faiss::HammingComputer4>(
|
|
538
|
+
4, a, b, na, nb, k, distances, labels);
|
|
539
|
+
break;
|
|
540
|
+
case 8:
|
|
541
|
+
// TODO(hoss): Write analog to hammings_knn_hc_1
|
|
542
|
+
// hammings_knn_hc_1 (ha, C64(a), C64(b), nb, order, true);
|
|
543
|
+
hammings_knn_mc<faiss::HammingComputer8>(
|
|
544
|
+
8, a, b, na, nb, k, distances, labels);
|
|
545
|
+
break;
|
|
546
|
+
case 16:
|
|
547
|
+
hammings_knn_mc<faiss::HammingComputer16>(
|
|
548
|
+
16, a, b, na, nb, k, distances, labels);
|
|
549
|
+
break;
|
|
550
|
+
case 32:
|
|
551
|
+
hammings_knn_mc<faiss::HammingComputer32>(
|
|
552
|
+
32, a, b, na, nb, k, distances, labels);
|
|
553
|
+
break;
|
|
554
|
+
default:
|
|
632
555
|
hammings_knn_mc<faiss::HammingComputerDefault>(
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
}
|
|
556
|
+
ncodes, a, b, na, nb, k, distances, labels);
|
|
557
|
+
break;
|
|
636
558
|
}
|
|
637
559
|
}
|
|
638
560
|
template <class HammingComputer>
|
|
639
|
-
static
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
RangeSearchResult *res)
|
|
648
|
-
{
|
|
649
|
-
|
|
561
|
+
static void hamming_range_search_template(
|
|
562
|
+
const uint8_t* a,
|
|
563
|
+
const uint8_t* b,
|
|
564
|
+
size_t na,
|
|
565
|
+
size_t nb,
|
|
566
|
+
int radius,
|
|
567
|
+
size_t code_size,
|
|
568
|
+
RangeSearchResult* res) {
|
|
650
569
|
#pragma omp parallel
|
|
651
570
|
{
|
|
652
|
-
RangeSearchPartialResult pres
|
|
571
|
+
RangeSearchPartialResult pres(res);
|
|
653
572
|
|
|
654
573
|
#pragma omp for
|
|
655
574
|
for (int64_t i = 0; i < na; i++) {
|
|
656
|
-
|
|
657
|
-
const uint8_t
|
|
658
|
-
RangeQueryResult
|
|
575
|
+
HammingComputer hc(a + i * code_size, code_size);
|
|
576
|
+
const uint8_t* yi = b;
|
|
577
|
+
RangeQueryResult& qres = pres.new_result(i);
|
|
659
578
|
|
|
660
579
|
for (size_t j = 0; j < nb; j++) {
|
|
661
|
-
int dis = hc.hamming
|
|
580
|
+
int dis = hc.hamming(yi);
|
|
662
581
|
if (dis < radius) {
|
|
663
582
|
qres.add(dis, j);
|
|
664
583
|
}
|
|
665
584
|
yi += code_size;
|
|
666
585
|
}
|
|
667
586
|
}
|
|
668
|
-
pres.finalize
|
|
587
|
+
pres.finalize();
|
|
669
588
|
}
|
|
670
589
|
}
|
|
671
590
|
|
|
672
|
-
void hamming_range_search
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
591
|
+
void hamming_range_search(
|
|
592
|
+
const uint8_t* a,
|
|
593
|
+
const uint8_t* b,
|
|
594
|
+
size_t na,
|
|
595
|
+
size_t nb,
|
|
596
|
+
int radius,
|
|
597
|
+
size_t code_size,
|
|
598
|
+
RangeSearchResult* result) {
|
|
599
|
+
#define HC(name) \
|
|
600
|
+
hamming_range_search_template<name>(a, b, na, nb, radius, code_size, result)
|
|
681
601
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
602
|
+
switch (code_size) {
|
|
603
|
+
case 4:
|
|
604
|
+
HC(HammingComputer4);
|
|
605
|
+
break;
|
|
606
|
+
case 8:
|
|
607
|
+
HC(HammingComputer8);
|
|
608
|
+
break;
|
|
609
|
+
case 16:
|
|
610
|
+
HC(HammingComputer16);
|
|
611
|
+
break;
|
|
612
|
+
case 32:
|
|
613
|
+
HC(HammingComputer32);
|
|
614
|
+
break;
|
|
615
|
+
default:
|
|
693
616
|
HC(HammingComputerDefault);
|
|
694
|
-
|
|
617
|
+
break;
|
|
695
618
|
}
|
|
696
619
|
#undef HC
|
|
697
620
|
}
|
|
698
621
|
|
|
699
|
-
|
|
700
|
-
|
|
701
622
|
/* Count number of matches given a max threshold */
|
|
702
|
-
void hamming_count_thres
|
|
703
|
-
const uint8_t
|
|
704
|
-
const uint8_t
|
|
623
|
+
void hamming_count_thres(
|
|
624
|
+
const uint8_t* bs1,
|
|
625
|
+
const uint8_t* bs2,
|
|
705
626
|
size_t n1,
|
|
706
627
|
size_t n2,
|
|
707
628
|
hamdis_t ht,
|
|
708
629
|
size_t ncodes,
|
|
709
|
-
size_t
|
|
710
|
-
{
|
|
630
|
+
size_t* nptr) {
|
|
711
631
|
switch (ncodes) {
|
|
712
632
|
case 8:
|
|
713
|
-
faiss::hamming_count_thres
|
|
714
|
-
|
|
633
|
+
faiss::hamming_count_thres<64>(
|
|
634
|
+
C64(bs1), C64(bs2), n1, n2, ht, nptr);
|
|
715
635
|
return;
|
|
716
636
|
case 16:
|
|
717
|
-
faiss::hamming_count_thres
|
|
718
|
-
|
|
637
|
+
faiss::hamming_count_thres<128>(
|
|
638
|
+
C64(bs1), C64(bs2), n1, n2, ht, nptr);
|
|
719
639
|
return;
|
|
720
640
|
case 32:
|
|
721
|
-
faiss::hamming_count_thres
|
|
722
|
-
|
|
641
|
+
faiss::hamming_count_thres<256>(
|
|
642
|
+
C64(bs1), C64(bs2), n1, n2, ht, nptr);
|
|
723
643
|
return;
|
|
724
644
|
case 64:
|
|
725
|
-
faiss::hamming_count_thres
|
|
726
|
-
|
|
645
|
+
faiss::hamming_count_thres<512>(
|
|
646
|
+
C64(bs1), C64(bs2), n1, n2, ht, nptr);
|
|
727
647
|
return;
|
|
728
648
|
default:
|
|
729
|
-
|
|
649
|
+
FAISS_THROW_FMT("not implemented for %zu bits", ncodes);
|
|
730
650
|
}
|
|
731
651
|
}
|
|
732
652
|
|
|
733
|
-
|
|
734
653
|
/* Count number of cross-matches given a threshold */
|
|
735
|
-
void crosshamming_count_thres
|
|
736
|
-
const uint8_t
|
|
654
|
+
void crosshamming_count_thres(
|
|
655
|
+
const uint8_t* dbs,
|
|
737
656
|
size_t n,
|
|
738
657
|
hamdis_t ht,
|
|
739
658
|
size_t ncodes,
|
|
740
|
-
size_t
|
|
741
|
-
{
|
|
659
|
+
size_t* nptr) {
|
|
742
660
|
switch (ncodes) {
|
|
743
661
|
case 8:
|
|
744
|
-
faiss::crosshamming_count_thres
|
|
662
|
+
faiss::crosshamming_count_thres<64>(C64(dbs), n, ht, nptr);
|
|
745
663
|
return;
|
|
746
664
|
case 16:
|
|
747
|
-
faiss::crosshamming_count_thres
|
|
665
|
+
faiss::crosshamming_count_thres<128>(C64(dbs), n, ht, nptr);
|
|
748
666
|
return;
|
|
749
667
|
case 32:
|
|
750
|
-
faiss::crosshamming_count_thres
|
|
668
|
+
faiss::crosshamming_count_thres<256>(C64(dbs), n, ht, nptr);
|
|
751
669
|
return;
|
|
752
670
|
case 64:
|
|
753
|
-
faiss::crosshamming_count_thres
|
|
671
|
+
faiss::crosshamming_count_thres<512>(C64(dbs), n, ht, nptr);
|
|
754
672
|
return;
|
|
755
673
|
default:
|
|
756
|
-
FAISS_THROW_FMT
|
|
674
|
+
FAISS_THROW_FMT("not implemented for %zu bits", ncodes);
|
|
757
675
|
}
|
|
758
676
|
}
|
|
759
677
|
|
|
760
|
-
|
|
761
678
|
/* Returns all matches given a threshold */
|
|
762
|
-
size_t match_hamming_thres
|
|
763
|
-
const uint8_t
|
|
764
|
-
const uint8_t
|
|
679
|
+
size_t match_hamming_thres(
|
|
680
|
+
const uint8_t* bs1,
|
|
681
|
+
const uint8_t* bs2,
|
|
765
682
|
size_t n1,
|
|
766
683
|
size_t n2,
|
|
767
684
|
hamdis_t ht,
|
|
768
685
|
size_t ncodes,
|
|
769
|
-
int64_t
|
|
770
|
-
hamdis_t
|
|
771
|
-
{
|
|
686
|
+
int64_t* idx,
|
|
687
|
+
hamdis_t* dis) {
|
|
772
688
|
switch (ncodes) {
|
|
773
689
|
case 8:
|
|
774
|
-
|
|
775
|
-
|
|
690
|
+
return faiss::match_hamming_thres<64>(
|
|
691
|
+
C64(bs1), C64(bs2), n1, n2, ht, idx, dis);
|
|
776
692
|
case 16:
|
|
777
|
-
|
|
778
|
-
|
|
693
|
+
return faiss::match_hamming_thres<128>(
|
|
694
|
+
C64(bs1), C64(bs2), n1, n2, ht, idx, dis);
|
|
779
695
|
case 32:
|
|
780
|
-
|
|
781
|
-
|
|
696
|
+
return faiss::match_hamming_thres<256>(
|
|
697
|
+
C64(bs1), C64(bs2), n1, n2, ht, idx, dis);
|
|
782
698
|
case 64:
|
|
783
|
-
|
|
784
|
-
|
|
699
|
+
return faiss::match_hamming_thres<512>(
|
|
700
|
+
C64(bs1), C64(bs2), n1, n2, ht, idx, dis);
|
|
785
701
|
default:
|
|
786
|
-
FAISS_THROW_FMT
|
|
702
|
+
FAISS_THROW_FMT("not implemented for %zu bits", ncodes);
|
|
787
703
|
return 0;
|
|
788
704
|
}
|
|
789
705
|
}
|
|
790
706
|
|
|
791
|
-
|
|
792
707
|
#undef C64
|
|
793
708
|
|
|
794
|
-
|
|
795
|
-
|
|
796
709
|
/*************************************
|
|
797
710
|
* generalized Hamming distances
|
|
798
711
|
************************************/
|
|
799
712
|
|
|
800
|
-
|
|
801
|
-
|
|
802
713
|
template <class HammingComputer>
|
|
803
|
-
static void hamming_dis_inner_loop
|
|
804
|
-
const uint8_t
|
|
805
|
-
const uint8_t
|
|
714
|
+
static void hamming_dis_inner_loop(
|
|
715
|
+
const uint8_t* ca,
|
|
716
|
+
const uint8_t* cb,
|
|
806
717
|
size_t nb,
|
|
807
718
|
size_t code_size,
|
|
808
719
|
int k,
|
|
809
|
-
hamdis_t
|
|
810
|
-
int64_t
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
HammingComputer hc (ca, code_size);
|
|
720
|
+
hamdis_t* bh_val_,
|
|
721
|
+
int64_t* bh_ids_) {
|
|
722
|
+
HammingComputer hc(ca, code_size);
|
|
814
723
|
|
|
815
724
|
for (size_t j = 0; j < nb; j++) {
|
|
816
|
-
int ndiff = hc.hamming
|
|
725
|
+
int ndiff = hc.hamming(cb);
|
|
817
726
|
cb += code_size;
|
|
818
727
|
if (ndiff < bh_val_[0]) {
|
|
819
|
-
maxheap_replace_top<hamdis_t>
|
|
728
|
+
maxheap_replace_top<hamdis_t>(k, bh_val_, bh_ids_, ndiff, j);
|
|
820
729
|
}
|
|
821
730
|
}
|
|
822
731
|
}
|
|
823
732
|
|
|
824
|
-
void generalized_hammings_knn_hc
|
|
825
|
-
int_maxheap_array_t
|
|
826
|
-
const uint8_t
|
|
827
|
-
const uint8_t
|
|
733
|
+
void generalized_hammings_knn_hc(
|
|
734
|
+
int_maxheap_array_t* ha,
|
|
735
|
+
const uint8_t* a,
|
|
736
|
+
const uint8_t* b,
|
|
828
737
|
size_t nb,
|
|
829
738
|
size_t code_size,
|
|
830
|
-
int ordered)
|
|
831
|
-
{
|
|
739
|
+
int ordered) {
|
|
832
740
|
int na = ha->nh;
|
|
833
741
|
int k = ha->k;
|
|
834
742
|
|
|
835
743
|
if (ordered)
|
|
836
|
-
ha->heapify
|
|
744
|
+
ha->heapify();
|
|
837
745
|
|
|
838
746
|
#pragma omp parallel for
|
|
839
747
|
for (int i = 0; i < na; i++) {
|
|
840
|
-
const uint8_t
|
|
841
|
-
const uint8_t
|
|
748
|
+
const uint8_t* ca = a + i * code_size;
|
|
749
|
+
const uint8_t* cb = b;
|
|
842
750
|
|
|
843
|
-
hamdis_t
|
|
844
|
-
int64_t
|
|
751
|
+
hamdis_t* bh_val_ = ha->val + i * k;
|
|
752
|
+
int64_t* bh_ids_ = ha->ids + i * k;
|
|
845
753
|
|
|
846
754
|
switch (code_size) {
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
755
|
+
case 8:
|
|
756
|
+
hamming_dis_inner_loop<GenHammingComputer8>(
|
|
757
|
+
ca, cb, nb, 8, k, bh_val_, bh_ids_);
|
|
758
|
+
break;
|
|
759
|
+
case 16:
|
|
760
|
+
hamming_dis_inner_loop<GenHammingComputer16>(
|
|
761
|
+
ca, cb, nb, 16, k, bh_val_, bh_ids_);
|
|
762
|
+
break;
|
|
763
|
+
case 32:
|
|
764
|
+
hamming_dis_inner_loop<GenHammingComputer32>(
|
|
765
|
+
ca, cb, nb, 32, k, bh_val_, bh_ids_);
|
|
766
|
+
break;
|
|
767
|
+
default:
|
|
768
|
+
hamming_dis_inner_loop<GenHammingComputerM8>(
|
|
769
|
+
ca, cb, nb, code_size, k, bh_val_, bh_ids_);
|
|
770
|
+
break;
|
|
863
771
|
}
|
|
864
772
|
}
|
|
865
773
|
|
|
866
774
|
if (ordered)
|
|
867
|
-
ha->reorder
|
|
868
|
-
|
|
775
|
+
ha->reorder();
|
|
869
776
|
}
|
|
870
777
|
|
|
871
|
-
|
|
872
778
|
} // namespace faiss
|