文件 pq4_fast_scan.h
-
namespace faiss
实现具有多种变体的 k-means 聚类。
版权所有 (c) Facebook, Inc. 及其附属公司。
此源代码已根据 MIT 许可证获得许可,该许可证位于此源树的根目录中的 LICENSE 文件中。
IDSelector 旨在定义要处理的向量子集(用于删除或作为搜索子集)
PQ4 SIMD 压缩和累加函数
基本内核使用 bbs = nb * 2 * 16 向量累加 nq 查询向量,并为此生成一个输出矩阵。 这对于 nq * nb <= 4 很有用,否则寄存器溢出变得太大。
这些函数的实现分布在 3 个 cpp 文件中,以减少并行编译时间。 模板被显式实例化。
此文件包含用于计算距离的内核的回调。
在整个库中,向量以 float * 指针的形式提供。 当在批处理中一起处理(添加/搜索)多个向量时,大多数算法都可以优化。 在这种情况下,它们作为矩阵传递。 当大小为 d 的 n 个向量作为 float * x 提供时,向量 i 的分量 j 是
x[ i * d + j ]
其中 0 <= i < n 且 0 <= j < d。 换句话说,矩阵始终是紧凑的。 当指定矩阵的大小时,我们称它为 n*d 矩阵,这意味着行优先存储。
I/O 函数可以读取/写入文件名、文件句柄或抽象介质的对象。
读取函数返回应该用 delete 释放的对象。 这些对象中的所有引用都归该对象所有。
反向列表的定义 + 一些实现该接口的常见类。
由于 IVF(倒排文件)索引对于大规模用例非常有用,我们将与它们相关的一些函数分组到这个小型库中。 大多数函数都适用于 IndexIVF 和嵌入在 IndexPreTransform 中的 IndexIVF。
在此文件中实现了 L2 和内积之外的额外度量
实现了一些神经网络层,主要用于支持 QINCo
定义了一些对一组向量应用转换的对象。 这些通常是预处理步骤。
函数
-
void pq4_pack_codes(const uint8_t *codes, size_t ntotal, size_t M, size_t nb, size_t bbs, size_t nsq, uint8_t *blocks)
打包代码以供 SIMD 内核使用。 未使用的字节设置为 0。
- 参数:
codes – 输入代码,大小 (ntotal, ceil(M / 2))
ntotal – 输入代码的数量
nb – 输出代码的数量(ntotal 四舍五入为 bbs 的倍数)
nsq – 子量化器的数量(= M 四舍五入为 2 的倍数)
bbs – 数据库块的大小(32 的倍数)
blocks – 输出数组,大小为 nb * nsq / 2。
-
void pq4_pack_codes_range(const uint8_t *codes, size_t M, size_t i0, size_t i1, size_t bbs, size_t nsq, uint8_t *blocks)
与 pack_codes 相同,但写入输出的给定范围,保持其余部分不变。 假设分配的条目在输入时为 0。
- 参数:
codes – 输入代码,大小为 (i1 - i0, ceil(M / 2))
i0 – 要写入的第一个输出代码
i1 – 要写入的最后一个输出代码
blocks – 输出数组,大小至少为 ceil(i1 / bbs) * bbs * nsq / 2
-
uint8_t pq4_get_packed_element(const uint8_t *data, size_t bbs, size_t nsq, size_t vector_id, size_t sq)
从打包的代码表中获取单个元素
- 参数:
vector_id – 向量 ID
sq – 子量化器 (< nsq)
-
void pq4_set_packed_element(uint8_t *data, uint8_t code, size_t bbs, size_t nsq, size_t vector_id, size_t sq)
将单个元素 “code” 设置到打包的代码表中
- 参数:
vector_id – 向量 ID
sq – 子量化器 (< nsq)
-
void pq4_pack_LUT(int nq, int nsq, const uint8_t *src, uint8_t *dest)
打包查找表以供内核使用。
- 参数:
nq – 查询的数量
nsq – 子量化器的数量(2 的倍数)
src – 输入数组,大小为 (nq, 16)
dest – 输出数组,大小为 (nq, 16)
-
void pq4_accumulate_loop(int nq, size_t nb, int bbs, int nsq, const uint8_t *codes, const uint8_t *LUT, SIMDResultHandler &res, const NormTableScaler *scaler)
循环遍历数据库元素并将结果累积到结果处理程序中
- 参数:
nq – 查询的数量
nb – 数据库元素的数量
bbs – 数据库块的大小(32 的倍数)
nsq – 子量化器的数量(2 的倍数)
codes – 打包的代码数组
LUT – 打包的查找表
scaler – 用于缩放编码范数的缩放器
-
int pq4_qbs_to_nq(int qbs)
-
int pq4_preferred_qbs(int nq)
返回查询数量 nb 的首选块分解。
-
int pq4_pack_LUT_qbs(int fqbs, int nsq, const uint8_t *src, uint8_t *dest)
打包查找表以供内核使用。
- 参数:
qbs – 4 位编码的查询块数,处理的总查询数 (nq) 由此推导得出
nsq – 子量化器的数量(2 的倍数)
src – 输入数组,大小为 (nq, 16)
dest – 输出数组,大小为 (nq, 16)
- 返回:
nq
-
int pq4_pack_LUT_qbs_q_map(int qbs, int nsq, const uint8_t *src, const int *q_map, uint8_t *dest)
与 pq4_pack_LUT_qbs 相同,只是源向量使用 q_map 重新映射
-
void pq4_accumulate_loop_qbs(int qbs, size_t nb, int nsq, const uint8_t *codes, const uint8_t *LUT, SIMDResultHandler &res, const NormTableScaler *scaler = nullptr)
运行累加循环。
- 参数:
qbs – 4 位编码的查询数量
nb – 数据库代码数量(bbs 的倍数)
nsq – 子量化器的数量
codes – 编码的数据库向量(打包)
LUT – 查找表(打包)
res – resutls 的回调
scaler – 用于缩放编码范数的缩放器
-
struct CodePackerPQ4 : public faiss::CodePacker
- #include <pq4_fast_scan.h>
用于 PQ4 快速扫描的 CodePacker API
公共函数
-
CodePackerPQ4(size_t nsq, size_t bbs)
-
virtual void pack_1(const uint8_t *flat_code, size_t offset, uint8_t *block) const final
-
virtual void unpack_1(const uint8_t *block, size_t offset, uint8_t *flat_code) const final
公共成员
-
size_t nsq
-
CodePackerPQ4(size_t nsq, size_t bbs)
-
void pq4_pack_codes(const uint8_t *codes, size_t ntotal, size_t M, size_t nb, size_t bbs, size_t nsq, uint8_t *blocks)