26 #ifndef FAISS_hamming_h
27 #define FAISS_hamming_h
37 typedef int32_t hamdis_t;
41 inline int popcount64(uint64_t x) {
42 return __builtin_popcountl(x);
60 void bitvec_print (
const uint8_t * b,
size_t d);
77 void fvec2bitvec (
const float * x, uint8_t * b,
size_t d);
89 int_maxheap_array_t * ha,
97 void hammings_knn_core (
98 int_maxheap_array_t * ha,
107 void hamming_count_thres (
118 size_t match_hamming_thres (
129 void crosshamming_count_thres (
139 const uint64_t * bs1,
140 const uint64_t * bs2,
159 assert (code_size == 4);
163 inline int hamming (
const uint8_t *b)
const {
164 return popcount64 (*(uint32_t *)b ^ a0);
173 assert (code_size == 8);
177 inline int hamming (
const uint8_t *b)
const {
178 return popcount64 (*(uint64_t *)b ^ a0);
187 assert (code_size == 16);
188 const uint64_t *a = (uint64_t *)a8;
189 a0 = a[0]; a1 = a[1];
192 inline int hamming (
const uint8_t *b8)
const {
193 const uint64_t *b = (uint64_t *)b8;
194 return popcount64 (b[0] ^ a0) + popcount64 (b[1] ^ a1);
206 assert (code_size == 20);
207 const uint64_t *a = (uint64_t *)a8;
208 a0 = a[0]; a1 = a[1]; a2 = a[2];
211 inline int hamming (
const uint8_t *b8)
const {
212 const uint64_t *b = (uint64_t *)b8;
213 return popcount64 (b[0] ^ a0) + popcount64 (b[1] ^ a1) +
214 popcount64 (*(uint32_t*)(b + 2) ^ a2);
219 uint64_t a0, a1, a2, a3;
222 assert (code_size == 32);
223 const uint64_t *a = (uint64_t *)a8;
224 a0 = a[0]; a1 = a[1]; a2 = a[2]; a3 = a[3];
227 inline int hamming (
const uint8_t *b8)
const {
228 const uint64_t *b = (uint64_t *)b8;
229 return popcount64 (b[0] ^ a0) + popcount64 (b[1] ^ a1) +
230 popcount64 (b[2] ^ a2) + popcount64 (b[3] ^ a3);
236 uint64_t a0, a1, a2, a3, a4, a5, a6, a7;
239 assert (code_size == 64);
240 const uint64_t *a = (uint64_t *)a8;
241 a0 = a[0]; a1 = a[1]; a2 = a[2]; a3 = a[3];
242 a4 = a[4]; a5 = a[5]; a6 = a[6]; a7 = a[7];
245 inline int hamming (
const uint8_t *b8)
const {
246 const uint64_t *b = (uint64_t *)b8;
247 return popcount64 (b[0] ^ a0) + popcount64 (b[1] ^ a1) +
248 popcount64 (b[2] ^ a2) + popcount64 (b[3] ^ a3) +
249 popcount64 (b[4] ^ a4) + popcount64 (b[5] ^ a5) +
250 popcount64 (b[6] ^ a6) + popcount64 (b[7] ^ a7);
264 int hamming (
const uint8_t *b8)
const {
266 for (
int i = 0; i < n; i++)
267 accu += popcount64 (a[i] ^ b8[i]);
279 assert (code_size % 8 == 0);
284 int hamming (
const uint8_t *b8)
const {
285 const uint64_t *b = (uint64_t *)b8;
287 for (
int i = 0; i < n; i++)
288 accu += popcount64 (a[i] ^ b[i]);
300 assert (code_size % 4 == 0);
304 int hamming (
const uint8_t *b8)
const {
305 const uint32_t *b = (uint32_t *)b8;
307 for (
int i = 0; i < n; i++)
308 accu += popcount64 (a[i] ^ b[i]);
319 template<
int CODE_SIZE>
325 #define SPECIALIZED_HC(CODE_SIZE) \
326 template<> struct HammingComputer<CODE_SIZE>: \
327 HammingComputer ## CODE_SIZE { \
328 HammingComputer (const uint8_t *a): \
329 HammingComputer ## CODE_SIZE(a, CODE_SIZE) {} \
339 #undef SPECIALIZED_HC
348 inline int generalized_hamming_64 (uint64_t a) {
352 a &= 0x0101010101010101UL;
353 return popcount64 (a);
361 assert (code_size == 8);
365 inline int hamming (
const uint8_t *b)
const {
366 return generalized_hamming_64 (*(uint64_t *)b ^ a0);
375 assert (code_size == 16);
376 const uint64_t *a = (uint64_t *)a8;
377 a0 = a[0]; a1 = a[1];
380 inline int hamming (
const uint8_t *b8)
const {
381 const uint64_t *b = (uint64_t *)b8;
382 return generalized_hamming_64 (b[0] ^ a0) +
383 generalized_hamming_64 (b[1] ^ a1);
389 uint64_t a0, a1, a2, a3;
392 assert (code_size == 32);
393 const uint64_t *a = (uint64_t *)a8;
394 a0 = a[0]; a1 = a[1]; a2 = a[2]; a3 = a[3];
397 inline int hamming (
const uint8_t *b8)
const {
398 const uint64_t *b = (uint64_t *)b8;
399 return generalized_hamming_64 (b[0] ^ a0) +
400 generalized_hamming_64 (b[1] ^ a1) +
401 generalized_hamming_64 (b[2] ^ a2) +
402 generalized_hamming_64 (b[3] ^ a3);
412 assert (code_size % 8 == 0);
417 int hamming (
const uint8_t *b8)
const {
418 const uint64_t *b = (uint64_t *)b8;
420 for (
int i = 0; i < n; i++)
421 accu += generalized_hamming_64 (a[i] ^ b[i]);
void generalized_hammings_knn(int_maxheap_array_t *ha, const uint8_t *a, const uint8_t *b, size_t nb, size_t code_size, int ordered)
void hammings_knn(int_maxheap_array_t *ha, const uint8_t *a, const uint8_t *b, size_t nb, size_t ncodes, int order)