2023-02-08 06:32:56 +08:00
|
|
|
/**
|
|
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
|
|
|
*/
|
|
|
|
|
Additional C++ templates for fast sa_decode: more codecs for Index2LevelDecoder (#2443)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2443
Add support for
* IVF[9-16 bit],PQ[1]x8 (such as IVF1024,PQ16np)
* Residual1x[9-16 bit],PQ[1]x8 (such as Residual1x9,PQ8)
Additionally, AVX2 and ARM versions support
* Residual[1]x8,PQ[2]x10
* Residual[1]x8,PQ[2]x16
* Residual1x[9-16 bit],PQ[1]x10 (such as Residual1x9,PQ16x10)
* Residual1x[9-16 bit],PQ[1]x16 (such as Residual1x9,PQ16x16)
* Residual[1]x10,PQ[2]x10
* Residual[1]x10,PQ[2]x16
* Residual[1]x16,PQ[2]x10
* Residual[1]x16,PQ[2]x16
IVF[9-16 bit],PQ[1]x10 and IVF[9-16 bit],PQ[1]x16 (such as IVF1024,PQ16x10np) are supported as well, but Faiss does not allow to train such Indices as this time.
Reviewed By: mdouze
Differential Revision: D39176424
fbshipit-source-id: 29b3d8d27a5fed0185df3e5484003fcc1521083a
2022-09-06 01:04:32 +08:00
|
|
|
// This test was designed to be run using valgrind or ASAN to test the
|
|
|
|
// correctness of memory accesses.
|
|
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <memory>
|
|
|
|
#include <random>
|
|
|
|
|
|
|
|
#include <faiss/utils/hamming.h>
|
|
|
|
|
|
|
|
#include <faiss/cppcontrib/detail/UintReader.h>
|
|
|
|
|
|
|
|
template <intptr_t N_ELEMENTS, intptr_t CODE_BITS, intptr_t CPOS>
|
|
|
|
struct TestLoop {
|
|
|
|
static void test(
|
|
|
|
const uint8_t* const container,
|
|
|
|
faiss::BitstringReader& br) {
|
|
|
|
// validate
|
|
|
|
const intptr_t uintreader_data = faiss::cppcontrib::detail::
|
|
|
|
UintReaderRaw<N_ELEMENTS, CODE_BITS, CPOS>::get(container);
|
|
|
|
const intptr_t bitstringreader_data = br.read(CODE_BITS);
|
|
|
|
|
|
|
|
ASSERT_EQ(uintreader_data, bitstringreader_data)
|
|
|
|
<< "Mismatch between BitstringReader (" << bitstringreader_data
|
|
|
|
<< ") and UintReader (" << uintreader_data
|
|
|
|
<< ") for N_ELEMENTS=" << N_ELEMENTS
|
|
|
|
<< ", CODE_BITS=" << CODE_BITS << ", CPOS=" << CPOS;
|
|
|
|
|
|
|
|
//
|
|
|
|
TestLoop<N_ELEMENTS, CODE_BITS, CPOS + 1>::test(container, br);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <intptr_t N_ELEMENTS, intptr_t CODE_BITS>
|
|
|
|
struct TestLoop<N_ELEMENTS, CODE_BITS, N_ELEMENTS> {
|
|
|
|
static void test(
|
|
|
|
const uint8_t* const container,
|
|
|
|
faiss::BitstringReader& br) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <intptr_t N_ELEMENTS, intptr_t CODE_BITS>
|
|
|
|
void TestUintReader() {
|
|
|
|
constexpr intptr_t CODE_BYTES = (CODE_BITS * N_ELEMENTS + 7) / 8;
|
|
|
|
|
|
|
|
std::default_random_engine rng;
|
|
|
|
std::uniform_int_distribution<uint64_t> u(0, 1 << CODE_BITS);
|
|
|
|
|
|
|
|
// do several attempts
|
|
|
|
for (size_t attempt = 0; attempt < 10; attempt++) {
|
|
|
|
// allocate a buffer. This way, not std::vector
|
|
|
|
std::unique_ptr<uint8_t[]> container(new uint8_t[CODE_BYTES]);
|
|
|
|
// make it empty
|
|
|
|
for (size_t i = 0; i < CODE_BYTES; i++) {
|
|
|
|
container.get()[i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// populate it
|
|
|
|
faiss::BitstringWriter bw(container.get(), CODE_BYTES);
|
|
|
|
for (size_t i = 0; i < N_ELEMENTS; i++) {
|
|
|
|
bw.write(u(rng), CODE_BITS);
|
|
|
|
}
|
|
|
|
|
|
|
|
// read it back and verify against bitreader
|
|
|
|
faiss::BitstringReader br(container.get(), CODE_BYTES);
|
|
|
|
|
|
|
|
TestLoop<N_ELEMENTS, CODE_BITS, 0>::test(container.get(), br);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <intptr_t CODE_BITS>
|
|
|
|
void TestUintReaderBits() {
|
|
|
|
TestUintReader<1, CODE_BITS>();
|
|
|
|
TestUintReader<2, CODE_BITS>();
|
|
|
|
TestUintReader<3, CODE_BITS>();
|
|
|
|
TestUintReader<4, CODE_BITS>();
|
|
|
|
TestUintReader<5, CODE_BITS>();
|
|
|
|
TestUintReader<6, CODE_BITS>();
|
|
|
|
TestUintReader<7, CODE_BITS>();
|
|
|
|
TestUintReader<8, CODE_BITS>();
|
|
|
|
TestUintReader<9, CODE_BITS>();
|
|
|
|
TestUintReader<10, CODE_BITS>();
|
|
|
|
TestUintReader<11, CODE_BITS>();
|
|
|
|
TestUintReader<12, CODE_BITS>();
|
|
|
|
TestUintReader<13, CODE_BITS>();
|
|
|
|
TestUintReader<14, CODE_BITS>();
|
|
|
|
TestUintReader<15, CODE_BITS>();
|
|
|
|
TestUintReader<16, CODE_BITS>();
|
|
|
|
TestUintReader<17, CODE_BITS>();
|
|
|
|
}
|
|
|
|
|
2023-08-14 23:03:40 +08:00
|
|
|
TEST(testCppcontribUintreader, Test8bit) {
|
Additional C++ templates for fast sa_decode: more codecs for Index2LevelDecoder (#2443)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2443
Add support for
* IVF[9-16 bit],PQ[1]x8 (such as IVF1024,PQ16np)
* Residual1x[9-16 bit],PQ[1]x8 (such as Residual1x9,PQ8)
Additionally, AVX2 and ARM versions support
* Residual[1]x8,PQ[2]x10
* Residual[1]x8,PQ[2]x16
* Residual1x[9-16 bit],PQ[1]x10 (such as Residual1x9,PQ16x10)
* Residual1x[9-16 bit],PQ[1]x16 (such as Residual1x9,PQ16x16)
* Residual[1]x10,PQ[2]x10
* Residual[1]x10,PQ[2]x16
* Residual[1]x16,PQ[2]x10
* Residual[1]x16,PQ[2]x16
IVF[9-16 bit],PQ[1]x10 and IVF[9-16 bit],PQ[1]x16 (such as IVF1024,PQ16x10np) are supported as well, but Faiss does not allow to train such Indices as this time.
Reviewed By: mdouze
Differential Revision: D39176424
fbshipit-source-id: 29b3d8d27a5fed0185df3e5484003fcc1521083a
2022-09-06 01:04:32 +08:00
|
|
|
TestUintReaderBits<8>();
|
|
|
|
}
|
|
|
|
|
2023-08-14 23:03:40 +08:00
|
|
|
TEST(testCppcontribUintreader, Test10bit) {
|
Additional C++ templates for fast sa_decode: more codecs for Index2LevelDecoder (#2443)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2443
Add support for
* IVF[9-16 bit],PQ[1]x8 (such as IVF1024,PQ16np)
* Residual1x[9-16 bit],PQ[1]x8 (such as Residual1x9,PQ8)
Additionally, AVX2 and ARM versions support
* Residual[1]x8,PQ[2]x10
* Residual[1]x8,PQ[2]x16
* Residual1x[9-16 bit],PQ[1]x10 (such as Residual1x9,PQ16x10)
* Residual1x[9-16 bit],PQ[1]x16 (such as Residual1x9,PQ16x16)
* Residual[1]x10,PQ[2]x10
* Residual[1]x10,PQ[2]x16
* Residual[1]x16,PQ[2]x10
* Residual[1]x16,PQ[2]x16
IVF[9-16 bit],PQ[1]x10 and IVF[9-16 bit],PQ[1]x16 (such as IVF1024,PQ16x10np) are supported as well, but Faiss does not allow to train such Indices as this time.
Reviewed By: mdouze
Differential Revision: D39176424
fbshipit-source-id: 29b3d8d27a5fed0185df3e5484003fcc1521083a
2022-09-06 01:04:32 +08:00
|
|
|
TestUintReaderBits<10>();
|
|
|
|
}
|
|
|
|
|
2023-08-14 23:03:40 +08:00
|
|
|
TEST(testCppcontribUintreader, Test12bit) {
|
2023-03-07 01:27:42 +08:00
|
|
|
TestUintReaderBits<12>();
|
|
|
|
}
|
|
|
|
|
2023-08-14 23:03:40 +08:00
|
|
|
TEST(testCppcontribUintreader, Test16bit) {
|
Additional C++ templates for fast sa_decode: more codecs for Index2LevelDecoder (#2443)
Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/2443
Add support for
* IVF[9-16 bit],PQ[1]x8 (such as IVF1024,PQ16np)
* Residual1x[9-16 bit],PQ[1]x8 (such as Residual1x9,PQ8)
Additionally, AVX2 and ARM versions support
* Residual[1]x8,PQ[2]x10
* Residual[1]x8,PQ[2]x16
* Residual1x[9-16 bit],PQ[1]x10 (such as Residual1x9,PQ16x10)
* Residual1x[9-16 bit],PQ[1]x16 (such as Residual1x9,PQ16x16)
* Residual[1]x10,PQ[2]x10
* Residual[1]x10,PQ[2]x16
* Residual[1]x16,PQ[2]x10
* Residual[1]x16,PQ[2]x16
IVF[9-16 bit],PQ[1]x10 and IVF[9-16 bit],PQ[1]x16 (such as IVF1024,PQ16x10np) are supported as well, but Faiss does not allow to train such Indices as this time.
Reviewed By: mdouze
Differential Revision: D39176424
fbshipit-source-id: 29b3d8d27a5fed0185df3e5484003fcc1521083a
2022-09-06 01:04:32 +08:00
|
|
|
TestUintReaderBits<16>();
|
|
|
|
}
|