| 349 | // luts must be of size [16][16] |
| 350 | template<int NBytes, class dist_t> |
| 351 | inline void lut_dists_4b(const uint8_t* codes, const dist_t* luts, |
| 352 | dist_t* dists_out, int64_t N) |
| 353 | { |
| 354 | static_assert(NBytes > 0, "Code length <= 0 is not valid"); |
| 355 | |
| 356 | for (int64_t i = 0; i < N; i++) { |
| 357 | dists_out[i] = 0; |
| 358 | auto lut_ptr = luts; |
| 359 | for (uint8_t j = 0; j < NBytes; j++) { |
| 360 | uint8_t code_high = static_cast<uint8_t>(codes[j] >> 4); |
| 361 | uint8_t code_low = static_cast<uint8_t>(codes[j] & mask_low4b); |
| 362 | |
| 363 | // // TODO rm after debug |
| 364 | // dists_out[i] += popcount(code_left ^ j); |
| 365 | // dists_out[i] += popcount(code_right ^ j); |
| 366 | |
| 367 | auto lut_low = lut_ptr; |
| 368 | auto lut_high = lut_low + 16; |
| 369 | dists_out[i] += lut_low[code_low]; |
| 370 | dists_out[i] += lut_high[code_high]; |
| 371 | // dists_out[i] += 42; |
| 372 | // auto dist = lut_low[code_low] + lut_high[code_high]; |
| 373 | // std::cout << "---- " << (int)j << "\n"; |
| 374 | // std::cout << "code: " << (int)codes[j] << "\n"; |
| 375 | // std::cout << "code_low: " << (int)code_low << "\n"; |
| 376 | // std::cout << "code_high: " << (int)code_high << "\n"; |
| 377 | // std::cout << "dist: " << (int)dist << "\n"; |
| 378 | // std::cout <i< "dist: " << (int)dist << "\n"; |
| 379 | lut_ptr += 32; |
| 380 | } |
| 381 | codes += NBytes; |
| 382 | } |
| 383 | } |
| 384 | |
| 385 | // non-vectorized NBytes-byte codes, where each byte is one codeword |
| 386 | template<int NBytes, class dist_t> |
nothing calls this directly
no outgoing calls
no test coverage detected