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
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
|
|
8
8
|
namespace faiss {
|
|
9
9
|
|
|
10
|
+
extern const uint8_t hamdis_tab_ham_bytes[256];
|
|
10
11
|
|
|
11
|
-
inline BitstringWriter::BitstringWriter(uint8_t
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
memset (code, 0, code_size);
|
|
12
|
+
inline BitstringWriter::BitstringWriter(uint8_t* code, size_t code_size)
|
|
13
|
+
: code(code), code_size(code_size), i(0) {
|
|
14
|
+
memset(code, 0, code_size);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
inline void BitstringWriter::write(uint64_t x, int nbit) {
|
|
18
|
-
assert
|
|
18
|
+
assert(code_size * 8 >= nbit + i);
|
|
19
19
|
// nb of available bits in i / 8
|
|
20
20
|
int na = 8 - (i & 7);
|
|
21
21
|
|
|
@@ -35,13 +35,11 @@ inline void BitstringWriter::write(uint64_t x, int nbit) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
code (code), code_size (code_size), i(0)
|
|
41
|
-
{}
|
|
38
|
+
inline BitstringReader::BitstringReader(const uint8_t* code, size_t code_size)
|
|
39
|
+
: code(code), code_size(code_size), i(0) {}
|
|
42
40
|
|
|
43
41
|
inline uint64_t BitstringReader::read(int nbit) {
|
|
44
|
-
assert
|
|
42
|
+
assert(code_size * 8 >= nbit + i);
|
|
45
43
|
// nb of available bits in i / 8
|
|
46
44
|
int na = 8 - (i & 7);
|
|
47
45
|
// get available bits in current byte
|
|
@@ -67,7 +65,6 @@ inline uint64_t BitstringReader::read(int nbit) {
|
|
|
67
65
|
}
|
|
68
66
|
}
|
|
69
67
|
|
|
70
|
-
|
|
71
68
|
/******************************************************************
|
|
72
69
|
* The HammingComputer series of classes compares a single code of
|
|
73
70
|
* size 4 to 32 to incoming codes. They are intended for use as a
|
|
@@ -76,68 +73,64 @@ inline uint64_t BitstringReader::read(int nbit) {
|
|
|
76
73
|
* hamming() functions and put the a0, a1, ... in registers.
|
|
77
74
|
******************************************************************/
|
|
78
75
|
|
|
79
|
-
|
|
80
76
|
struct HammingComputer4 {
|
|
81
77
|
uint32_t a0;
|
|
82
78
|
|
|
83
|
-
HammingComputer4
|
|
79
|
+
HammingComputer4() {}
|
|
84
80
|
|
|
85
|
-
HammingComputer4
|
|
86
|
-
set
|
|
81
|
+
HammingComputer4(const uint8_t* a, int code_size) {
|
|
82
|
+
set(a, code_size);
|
|
87
83
|
}
|
|
88
84
|
|
|
89
|
-
void set
|
|
90
|
-
assert
|
|
91
|
-
a0 = *(uint32_t
|
|
85
|
+
void set(const uint8_t* a, int code_size) {
|
|
86
|
+
assert(code_size == 4);
|
|
87
|
+
a0 = *(uint32_t*)a;
|
|
92
88
|
}
|
|
93
89
|
|
|
94
|
-
inline int hamming
|
|
95
|
-
return popcount64
|
|
90
|
+
inline int hamming(const uint8_t* b) const {
|
|
91
|
+
return popcount64(*(uint32_t*)b ^ a0);
|
|
96
92
|
}
|
|
97
|
-
|
|
98
93
|
};
|
|
99
94
|
|
|
100
95
|
struct HammingComputer8 {
|
|
101
96
|
uint64_t a0;
|
|
102
97
|
|
|
103
|
-
HammingComputer8
|
|
98
|
+
HammingComputer8() {}
|
|
104
99
|
|
|
105
|
-
HammingComputer8
|
|
106
|
-
set
|
|
100
|
+
HammingComputer8(const uint8_t* a, int code_size) {
|
|
101
|
+
set(a, code_size);
|
|
107
102
|
}
|
|
108
103
|
|
|
109
|
-
void set
|
|
110
|
-
assert
|
|
111
|
-
a0 = *(uint64_t
|
|
104
|
+
void set(const uint8_t* a, int code_size) {
|
|
105
|
+
assert(code_size == 8);
|
|
106
|
+
a0 = *(uint64_t*)a;
|
|
112
107
|
}
|
|
113
108
|
|
|
114
|
-
inline int hamming
|
|
115
|
-
return popcount64
|
|
109
|
+
inline int hamming(const uint8_t* b) const {
|
|
110
|
+
return popcount64(*(uint64_t*)b ^ a0);
|
|
116
111
|
}
|
|
117
|
-
|
|
118
112
|
};
|
|
119
113
|
|
|
120
|
-
|
|
121
114
|
struct HammingComputer16 {
|
|
122
115
|
uint64_t a0, a1;
|
|
123
116
|
|
|
124
|
-
HammingComputer16
|
|
117
|
+
HammingComputer16() {}
|
|
125
118
|
|
|
126
|
-
HammingComputer16
|
|
127
|
-
set
|
|
119
|
+
HammingComputer16(const uint8_t* a8, int code_size) {
|
|
120
|
+
set(a8, code_size);
|
|
128
121
|
}
|
|
129
122
|
|
|
130
|
-
void set
|
|
131
|
-
assert
|
|
132
|
-
const uint64_t
|
|
133
|
-
a0 = a[0];
|
|
123
|
+
void set(const uint8_t* a8, int code_size) {
|
|
124
|
+
assert(code_size == 16);
|
|
125
|
+
const uint64_t* a = (uint64_t*)a8;
|
|
126
|
+
a0 = a[0];
|
|
127
|
+
a1 = a[1];
|
|
134
128
|
}
|
|
135
129
|
|
|
136
|
-
inline int hamming
|
|
137
|
-
const uint64_t
|
|
138
|
-
return popcount64
|
|
130
|
+
inline int hamming(const uint8_t* b8) const {
|
|
131
|
+
const uint64_t* b = (uint64_t*)b8;
|
|
132
|
+
return popcount64(b[0] ^ a0) + popcount64(b[1] ^ a1);
|
|
139
133
|
}
|
|
140
|
-
|
|
141
134
|
};
|
|
142
135
|
|
|
143
136
|
// when applied to an array, 1/2 of the 64-bit accesses are unaligned.
|
|
@@ -146,150 +139,212 @@ struct HammingComputer20 {
|
|
|
146
139
|
uint64_t a0, a1;
|
|
147
140
|
uint32_t a2;
|
|
148
141
|
|
|
149
|
-
HammingComputer20
|
|
142
|
+
HammingComputer20() {}
|
|
150
143
|
|
|
151
|
-
HammingComputer20
|
|
152
|
-
set
|
|
144
|
+
HammingComputer20(const uint8_t* a8, int code_size) {
|
|
145
|
+
set(a8, code_size);
|
|
153
146
|
}
|
|
154
147
|
|
|
155
|
-
void set
|
|
156
|
-
assert
|
|
157
|
-
const uint64_t
|
|
158
|
-
a0 = a[0];
|
|
148
|
+
void set(const uint8_t* a8, int code_size) {
|
|
149
|
+
assert(code_size == 20);
|
|
150
|
+
const uint64_t* a = (uint64_t*)a8;
|
|
151
|
+
a0 = a[0];
|
|
152
|
+
a1 = a[1];
|
|
153
|
+
a2 = a[2];
|
|
159
154
|
}
|
|
160
155
|
|
|
161
|
-
inline int hamming
|
|
162
|
-
const uint64_t
|
|
163
|
-
return popcount64
|
|
164
|
-
|
|
156
|
+
inline int hamming(const uint8_t* b8) const {
|
|
157
|
+
const uint64_t* b = (uint64_t*)b8;
|
|
158
|
+
return popcount64(b[0] ^ a0) + popcount64(b[1] ^ a1) +
|
|
159
|
+
popcount64(*(uint32_t*)(b + 2) ^ a2);
|
|
165
160
|
}
|
|
166
161
|
};
|
|
167
162
|
|
|
168
163
|
struct HammingComputer32 {
|
|
169
164
|
uint64_t a0, a1, a2, a3;
|
|
170
165
|
|
|
171
|
-
HammingComputer32
|
|
166
|
+
HammingComputer32() {}
|
|
172
167
|
|
|
173
|
-
HammingComputer32
|
|
174
|
-
set
|
|
168
|
+
HammingComputer32(const uint8_t* a8, int code_size) {
|
|
169
|
+
set(a8, code_size);
|
|
175
170
|
}
|
|
176
171
|
|
|
177
|
-
void set
|
|
178
|
-
assert
|
|
179
|
-
const uint64_t
|
|
180
|
-
a0 = a[0];
|
|
172
|
+
void set(const uint8_t* a8, int code_size) {
|
|
173
|
+
assert(code_size == 32);
|
|
174
|
+
const uint64_t* a = (uint64_t*)a8;
|
|
175
|
+
a0 = a[0];
|
|
176
|
+
a1 = a[1];
|
|
177
|
+
a2 = a[2];
|
|
178
|
+
a3 = a[3];
|
|
181
179
|
}
|
|
182
180
|
|
|
183
|
-
inline int hamming
|
|
184
|
-
const uint64_t
|
|
185
|
-
return popcount64
|
|
186
|
-
|
|
181
|
+
inline int hamming(const uint8_t* b8) const {
|
|
182
|
+
const uint64_t* b = (uint64_t*)b8;
|
|
183
|
+
return popcount64(b[0] ^ a0) + popcount64(b[1] ^ a1) +
|
|
184
|
+
popcount64(b[2] ^ a2) + popcount64(b[3] ^ a3);
|
|
187
185
|
}
|
|
188
|
-
|
|
189
186
|
};
|
|
190
187
|
|
|
191
188
|
struct HammingComputer64 {
|
|
192
189
|
uint64_t a0, a1, a2, a3, a4, a5, a6, a7;
|
|
193
190
|
|
|
194
|
-
HammingComputer64
|
|
191
|
+
HammingComputer64() {}
|
|
195
192
|
|
|
196
|
-
HammingComputer64
|
|
197
|
-
set
|
|
193
|
+
HammingComputer64(const uint8_t* a8, int code_size) {
|
|
194
|
+
set(a8, code_size);
|
|
198
195
|
}
|
|
199
196
|
|
|
200
|
-
void set
|
|
201
|
-
assert
|
|
202
|
-
const uint64_t
|
|
203
|
-
a0 = a[0];
|
|
204
|
-
|
|
197
|
+
void set(const uint8_t* a8, int code_size) {
|
|
198
|
+
assert(code_size == 64);
|
|
199
|
+
const uint64_t* a = (uint64_t*)a8;
|
|
200
|
+
a0 = a[0];
|
|
201
|
+
a1 = a[1];
|
|
202
|
+
a2 = a[2];
|
|
203
|
+
a3 = a[3];
|
|
204
|
+
a4 = a[4];
|
|
205
|
+
a5 = a[5];
|
|
206
|
+
a6 = a[6];
|
|
207
|
+
a7 = a[7];
|
|
205
208
|
}
|
|
206
209
|
|
|
207
|
-
inline int hamming
|
|
208
|
-
const uint64_t
|
|
209
|
-
return popcount64
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
inline int hamming(const uint8_t* b8) const {
|
|
211
|
+
const uint64_t* b = (uint64_t*)b8;
|
|
212
|
+
return popcount64(b[0] ^ a0) + popcount64(b[1] ^ a1) +
|
|
213
|
+
popcount64(b[2] ^ a2) + popcount64(b[3] ^ a3) +
|
|
214
|
+
popcount64(b[4] ^ a4) + popcount64(b[5] ^ a5) +
|
|
215
|
+
popcount64(b[6] ^ a6) + popcount64(b[7] ^ a7);
|
|
213
216
|
}
|
|
214
|
-
|
|
215
217
|
};
|
|
216
218
|
|
|
217
|
-
// very inefficient...
|
|
218
219
|
struct HammingComputerDefault {
|
|
219
|
-
const uint8_t
|
|
220
|
-
int
|
|
220
|
+
const uint8_t* a8;
|
|
221
|
+
int quotient8;
|
|
222
|
+
int remainder8;
|
|
221
223
|
|
|
222
|
-
HammingComputerDefault
|
|
224
|
+
HammingComputerDefault() {}
|
|
223
225
|
|
|
224
|
-
HammingComputerDefault
|
|
225
|
-
set
|
|
226
|
+
HammingComputerDefault(const uint8_t* a8, int code_size) {
|
|
227
|
+
set(a8, code_size);
|
|
226
228
|
}
|
|
227
229
|
|
|
228
|
-
void set
|
|
229
|
-
|
|
230
|
-
|
|
230
|
+
void set(const uint8_t* a8, int code_size) {
|
|
231
|
+
this->a8 = a8;
|
|
232
|
+
quotient8 = code_size / 8;
|
|
233
|
+
remainder8 = code_size % 8;
|
|
231
234
|
}
|
|
232
235
|
|
|
233
|
-
int hamming
|
|
236
|
+
int hamming(const uint8_t* b8) const {
|
|
234
237
|
int accu = 0;
|
|
235
|
-
|
|
236
|
-
|
|
238
|
+
|
|
239
|
+
const uint64_t* a64 = reinterpret_cast<const uint64_t*>(a8);
|
|
240
|
+
const uint64_t* b64 = reinterpret_cast<const uint64_t*>(b8);
|
|
241
|
+
int i = 0, len = quotient8;
|
|
242
|
+
switch (len & 7) {
|
|
243
|
+
default:
|
|
244
|
+
while (len > 7) {
|
|
245
|
+
len -= 8;
|
|
246
|
+
accu += popcount64(a64[i] ^ b64[i]);
|
|
247
|
+
i++;
|
|
248
|
+
case 7:
|
|
249
|
+
accu += popcount64(a64[i] ^ b64[i]);
|
|
250
|
+
i++;
|
|
251
|
+
case 6:
|
|
252
|
+
accu += popcount64(a64[i] ^ b64[i]);
|
|
253
|
+
i++;
|
|
254
|
+
case 5:
|
|
255
|
+
accu += popcount64(a64[i] ^ b64[i]);
|
|
256
|
+
i++;
|
|
257
|
+
case 4:
|
|
258
|
+
accu += popcount64(a64[i] ^ b64[i]);
|
|
259
|
+
i++;
|
|
260
|
+
case 3:
|
|
261
|
+
accu += popcount64(a64[i] ^ b64[i]);
|
|
262
|
+
i++;
|
|
263
|
+
case 2:
|
|
264
|
+
accu += popcount64(a64[i] ^ b64[i]);
|
|
265
|
+
i++;
|
|
266
|
+
case 1:
|
|
267
|
+
accu += popcount64(a64[i] ^ b64[i]);
|
|
268
|
+
i++;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (remainder8) {
|
|
272
|
+
const uint8_t* a = a8 + 8 * quotient8;
|
|
273
|
+
const uint8_t* b = b8 + 8 * quotient8;
|
|
274
|
+
switch (remainder8) {
|
|
275
|
+
case 7:
|
|
276
|
+
accu += hamdis_tab_ham_bytes[a[6] ^ b[6]];
|
|
277
|
+
case 6:
|
|
278
|
+
accu += hamdis_tab_ham_bytes[a[5] ^ b[5]];
|
|
279
|
+
case 5:
|
|
280
|
+
accu += hamdis_tab_ham_bytes[a[4] ^ b[4]];
|
|
281
|
+
case 4:
|
|
282
|
+
accu += hamdis_tab_ham_bytes[a[3] ^ b[3]];
|
|
283
|
+
case 3:
|
|
284
|
+
accu += hamdis_tab_ham_bytes[a[2] ^ b[2]];
|
|
285
|
+
case 2:
|
|
286
|
+
accu += hamdis_tab_ham_bytes[a[1] ^ b[1]];
|
|
287
|
+
case 1:
|
|
288
|
+
accu += hamdis_tab_ham_bytes[a[0] ^ b[0]];
|
|
289
|
+
default:
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
237
294
|
return accu;
|
|
238
295
|
}
|
|
239
|
-
|
|
240
296
|
};
|
|
241
297
|
|
|
298
|
+
// more inefficient than HammingComputerDefault (obsolete)
|
|
242
299
|
struct HammingComputerM8 {
|
|
243
|
-
const uint64_t
|
|
300
|
+
const uint64_t* a;
|
|
244
301
|
int n;
|
|
245
302
|
|
|
246
|
-
HammingComputerM8
|
|
303
|
+
HammingComputerM8() {}
|
|
247
304
|
|
|
248
|
-
HammingComputerM8
|
|
249
|
-
set
|
|
305
|
+
HammingComputerM8(const uint8_t* a8, int code_size) {
|
|
306
|
+
set(a8, code_size);
|
|
250
307
|
}
|
|
251
308
|
|
|
252
|
-
void set
|
|
253
|
-
assert
|
|
254
|
-
a =
|
|
309
|
+
void set(const uint8_t* a8, int code_size) {
|
|
310
|
+
assert(code_size % 8 == 0);
|
|
311
|
+
a = (uint64_t*)a8;
|
|
255
312
|
n = code_size / 8;
|
|
256
313
|
}
|
|
257
314
|
|
|
258
|
-
int hamming
|
|
259
|
-
const uint64_t
|
|
315
|
+
int hamming(const uint8_t* b8) const {
|
|
316
|
+
const uint64_t* b = (uint64_t*)b8;
|
|
260
317
|
int accu = 0;
|
|
261
318
|
for (int i = 0; i < n; i++)
|
|
262
|
-
accu += popcount64
|
|
319
|
+
accu += popcount64(a[i] ^ b[i]);
|
|
263
320
|
return accu;
|
|
264
321
|
}
|
|
265
|
-
|
|
266
322
|
};
|
|
267
323
|
|
|
268
|
-
//
|
|
324
|
+
// more inefficient than HammingComputerDefault (obsolete)
|
|
269
325
|
struct HammingComputerM4 {
|
|
270
|
-
const uint32_t
|
|
326
|
+
const uint32_t* a;
|
|
271
327
|
int n;
|
|
272
328
|
|
|
273
|
-
HammingComputerM4
|
|
329
|
+
HammingComputerM4() {}
|
|
274
330
|
|
|
275
|
-
HammingComputerM4
|
|
276
|
-
set
|
|
331
|
+
HammingComputerM4(const uint8_t* a4, int code_size) {
|
|
332
|
+
set(a4, code_size);
|
|
277
333
|
}
|
|
278
334
|
|
|
279
|
-
void set
|
|
280
|
-
assert
|
|
281
|
-
a =
|
|
335
|
+
void set(const uint8_t* a4, int code_size) {
|
|
336
|
+
assert(code_size % 4 == 0);
|
|
337
|
+
a = (uint32_t*)a4;
|
|
282
338
|
n = code_size / 4;
|
|
283
339
|
}
|
|
284
340
|
|
|
285
|
-
int hamming
|
|
286
|
-
const uint32_t
|
|
341
|
+
int hamming(const uint8_t* b8) const {
|
|
342
|
+
const uint32_t* b = (uint32_t*)b8;
|
|
287
343
|
int accu = 0;
|
|
288
344
|
for (int i = 0; i < n; i++)
|
|
289
|
-
|
|
345
|
+
accu += popcount64(a[i] ^ b[i]);
|
|
290
346
|
return accu;
|
|
291
347
|
}
|
|
292
|
-
|
|
293
348
|
};
|
|
294
349
|
|
|
295
350
|
/***************************************************************************
|
|
@@ -297,17 +352,17 @@ struct HammingComputerM4 {
|
|
|
297
352
|
**************************************************************************/
|
|
298
353
|
|
|
299
354
|
// default template
|
|
300
|
-
template<int CODE_SIZE>
|
|
301
|
-
struct HammingComputer:
|
|
302
|
-
HammingComputer
|
|
303
|
-
|
|
355
|
+
template <int CODE_SIZE>
|
|
356
|
+
struct HammingComputer : HammingComputerDefault {
|
|
357
|
+
HammingComputer(const uint8_t* a, int code_size)
|
|
358
|
+
: HammingComputerDefault(a, code_size) {}
|
|
304
359
|
};
|
|
305
360
|
|
|
306
|
-
#define SPECIALIZED_HC(CODE_SIZE)
|
|
307
|
-
template<>
|
|
308
|
-
|
|
309
|
-
HammingComputer
|
|
310
|
-
|
|
361
|
+
#define SPECIALIZED_HC(CODE_SIZE) \
|
|
362
|
+
template <> \
|
|
363
|
+
struct HammingComputer<CODE_SIZE> : HammingComputer##CODE_SIZE { \
|
|
364
|
+
HammingComputer(const uint8_t* a) \
|
|
365
|
+
: HammingComputer##CODE_SIZE(a, CODE_SIZE) {} \
|
|
311
366
|
}
|
|
312
367
|
|
|
313
368
|
SPECIALIZED_HC(4);
|
|
@@ -319,105 +374,98 @@ SPECIALIZED_HC(64);
|
|
|
319
374
|
|
|
320
375
|
#undef SPECIALIZED_HC
|
|
321
376
|
|
|
322
|
-
|
|
323
377
|
/***************************************************************************
|
|
324
378
|
* generalized Hamming = number of bytes that are different between
|
|
325
379
|
* two codes.
|
|
326
380
|
***************************************************************************/
|
|
327
381
|
|
|
328
|
-
|
|
329
|
-
inline int generalized_hamming_64 (uint64_t a) {
|
|
382
|
+
inline int generalized_hamming_64(uint64_t a) {
|
|
330
383
|
a |= a >> 1;
|
|
331
384
|
a |= a >> 2;
|
|
332
385
|
a |= a >> 4;
|
|
333
386
|
a &= 0x0101010101010101UL;
|
|
334
|
-
return popcount64
|
|
387
|
+
return popcount64(a);
|
|
335
388
|
}
|
|
336
389
|
|
|
337
|
-
|
|
338
390
|
struct GenHammingComputer8 {
|
|
339
391
|
uint64_t a0;
|
|
340
392
|
|
|
341
|
-
GenHammingComputer8
|
|
342
|
-
assert
|
|
343
|
-
a0 = *(uint64_t
|
|
393
|
+
GenHammingComputer8(const uint8_t* a, int code_size) {
|
|
394
|
+
assert(code_size == 8);
|
|
395
|
+
a0 = *(uint64_t*)a;
|
|
344
396
|
}
|
|
345
397
|
|
|
346
|
-
inline int hamming
|
|
347
|
-
return generalized_hamming_64
|
|
398
|
+
inline int hamming(const uint8_t* b) const {
|
|
399
|
+
return generalized_hamming_64(*(uint64_t*)b ^ a0);
|
|
348
400
|
}
|
|
349
|
-
|
|
350
401
|
};
|
|
351
402
|
|
|
352
|
-
|
|
353
403
|
struct GenHammingComputer16 {
|
|
354
404
|
uint64_t a0, a1;
|
|
355
|
-
GenHammingComputer16
|
|
356
|
-
assert
|
|
357
|
-
const uint64_t
|
|
358
|
-
a0 = a[0];
|
|
405
|
+
GenHammingComputer16(const uint8_t* a8, int code_size) {
|
|
406
|
+
assert(code_size == 16);
|
|
407
|
+
const uint64_t* a = (uint64_t*)a8;
|
|
408
|
+
a0 = a[0];
|
|
409
|
+
a1 = a[1];
|
|
359
410
|
}
|
|
360
411
|
|
|
361
|
-
inline int hamming
|
|
362
|
-
const uint64_t
|
|
363
|
-
return generalized_hamming_64
|
|
364
|
-
|
|
412
|
+
inline int hamming(const uint8_t* b8) const {
|
|
413
|
+
const uint64_t* b = (uint64_t*)b8;
|
|
414
|
+
return generalized_hamming_64(b[0] ^ a0) +
|
|
415
|
+
generalized_hamming_64(b[1] ^ a1);
|
|
365
416
|
}
|
|
366
|
-
|
|
367
417
|
};
|
|
368
418
|
|
|
369
419
|
struct GenHammingComputer32 {
|
|
370
420
|
uint64_t a0, a1, a2, a3;
|
|
371
421
|
|
|
372
|
-
GenHammingComputer32
|
|
373
|
-
assert
|
|
374
|
-
const uint64_t
|
|
375
|
-
a0 = a[0];
|
|
422
|
+
GenHammingComputer32(const uint8_t* a8, int code_size) {
|
|
423
|
+
assert(code_size == 32);
|
|
424
|
+
const uint64_t* a = (uint64_t*)a8;
|
|
425
|
+
a0 = a[0];
|
|
426
|
+
a1 = a[1];
|
|
427
|
+
a2 = a[2];
|
|
428
|
+
a3 = a[3];
|
|
376
429
|
}
|
|
377
430
|
|
|
378
|
-
inline int hamming
|
|
379
|
-
const uint64_t
|
|
380
|
-
return generalized_hamming_64
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
431
|
+
inline int hamming(const uint8_t* b8) const {
|
|
432
|
+
const uint64_t* b = (uint64_t*)b8;
|
|
433
|
+
return generalized_hamming_64(b[0] ^ a0) +
|
|
434
|
+
generalized_hamming_64(b[1] ^ a1) +
|
|
435
|
+
generalized_hamming_64(b[2] ^ a2) +
|
|
436
|
+
generalized_hamming_64(b[3] ^ a3);
|
|
384
437
|
}
|
|
385
|
-
|
|
386
438
|
};
|
|
387
439
|
|
|
388
440
|
struct GenHammingComputerM8 {
|
|
389
|
-
const uint64_t
|
|
441
|
+
const uint64_t* a;
|
|
390
442
|
int n;
|
|
391
443
|
|
|
392
|
-
GenHammingComputerM8
|
|
393
|
-
assert
|
|
394
|
-
a =
|
|
444
|
+
GenHammingComputerM8(const uint8_t* a8, int code_size) {
|
|
445
|
+
assert(code_size % 8 == 0);
|
|
446
|
+
a = (uint64_t*)a8;
|
|
395
447
|
n = code_size / 8;
|
|
396
448
|
}
|
|
397
449
|
|
|
398
|
-
int hamming
|
|
399
|
-
const uint64_t
|
|
450
|
+
int hamming(const uint8_t* b8) const {
|
|
451
|
+
const uint64_t* b = (uint64_t*)b8;
|
|
400
452
|
int accu = 0;
|
|
401
453
|
for (int i = 0; i < n; i++)
|
|
402
|
-
accu += generalized_hamming_64
|
|
454
|
+
accu += generalized_hamming_64(a[i] ^ b[i]);
|
|
403
455
|
return accu;
|
|
404
456
|
}
|
|
405
|
-
|
|
406
457
|
};
|
|
407
458
|
|
|
408
|
-
|
|
409
459
|
/** generalized Hamming distances (= count number of code bytes that
|
|
410
460
|
are the same) */
|
|
411
|
-
void generalized_hammings_knn_hc
|
|
412
|
-
int_maxheap_array_t
|
|
413
|
-
const uint8_t
|
|
414
|
-
const uint8_t
|
|
461
|
+
void generalized_hammings_knn_hc(
|
|
462
|
+
int_maxheap_array_t* ha,
|
|
463
|
+
const uint8_t* a,
|
|
464
|
+
const uint8_t* b,
|
|
415
465
|
size_t nb,
|
|
416
466
|
size_t code_size,
|
|
417
467
|
int ordered = true);
|
|
418
468
|
|
|
419
|
-
|
|
420
|
-
|
|
421
469
|
/** This class maintains a list of best distances seen so far.
|
|
422
470
|
*
|
|
423
471
|
* Since the distances are in a limited range (0 to nbit), the
|
|
@@ -425,46 +473,49 @@ void generalized_hammings_knn_hc (
|
|
|
425
473
|
* in only the n-first lists, such that the sum of sizes of the
|
|
426
474
|
* n lists is below k.
|
|
427
475
|
*/
|
|
428
|
-
template<class HammingComputer>
|
|
476
|
+
template <class HammingComputer>
|
|
429
477
|
struct HCounterState {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
478
|
+
int* counters;
|
|
479
|
+
int64_t* ids_per_dis;
|
|
480
|
+
|
|
481
|
+
HammingComputer hc;
|
|
482
|
+
int thres;
|
|
483
|
+
int count_lt;
|
|
484
|
+
int count_eq;
|
|
485
|
+
int k;
|
|
486
|
+
|
|
487
|
+
HCounterState(
|
|
488
|
+
int* counters,
|
|
489
|
+
int64_t* ids_per_dis,
|
|
490
|
+
const uint8_t* x,
|
|
491
|
+
int d,
|
|
492
|
+
int k)
|
|
493
|
+
: counters(counters),
|
|
494
|
+
ids_per_dis(ids_per_dis),
|
|
495
|
+
hc(x, d / 8),
|
|
496
|
+
thres(d + 1),
|
|
497
|
+
count_lt(0),
|
|
498
|
+
count_eq(0),
|
|
499
|
+
k(k) {}
|
|
500
|
+
|
|
501
|
+
void update_counter(const uint8_t* y, size_t j) {
|
|
502
|
+
int32_t dis = hc.hamming(y);
|
|
503
|
+
|
|
504
|
+
if (dis <= thres) {
|
|
505
|
+
if (dis < thres) {
|
|
506
|
+
ids_per_dis[dis * k + counters[dis]++] = j;
|
|
507
|
+
++count_lt;
|
|
508
|
+
while (count_lt == k && thres > 0) {
|
|
509
|
+
--thres;
|
|
510
|
+
count_eq = counters[thres];
|
|
511
|
+
count_lt -= count_eq;
|
|
512
|
+
}
|
|
513
|
+
} else if (count_eq < k) {
|
|
514
|
+
ids_per_dis[dis * k + count_eq++] = j;
|
|
515
|
+
counters[dis] = count_eq;
|
|
516
|
+
}
|
|
460
517
|
}
|
|
461
|
-
} else if (count_eq < k) {
|
|
462
|
-
ids_per_dis[dis * k + count_eq++] = j;
|
|
463
|
-
counters[dis] = count_eq;
|
|
464
|
-
}
|
|
465
518
|
}
|
|
466
|
-
}
|
|
467
519
|
};
|
|
468
520
|
|
|
469
|
-
|
|
470
521
|
} // namespace faiss
|