2#ifndef NO_MANUAL_VECTORIZATION
14#if defined(USE_AVX) || defined(USE_SSE)
19void cpu_x86::cpuid(int32_t out[4], int32_t eax, int32_t ecx) {
20 __cpuidex(out, eax, ecx);
22__int64 xgetbv(
unsigned int x) {
29void cpuid(int32_t cpuInfo[4], int32_t eax, int32_t ecx) {
30 __cpuid_count(eax, ecx, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]);
32uint64_t xgetbv(
unsigned int index) {
34 __asm__ __volatile__(
"xgetbv" :
"=a"(eax),
"=d"(edx) :
"c"(index));
35 return ((uint64_t)edx << 32) | eax;
39#if defined(USE_AVX512)
44#define PORTABLE_ALIGN32 __attribute__((aligned(32)))
45#define PORTABLE_ALIGN64 __attribute__((aligned(64)))
47#define PORTABLE_ALIGN32 __declspec(align(32))
48#define PORTABLE_ALIGN64 __declspec(align(64))
52#define _XCR_XFEATURE_ENABLED_MASK 0
59 int nIds = cpuInfo[0];
62 if (nIds >= 0x00000001) {
63 cpuid(cpuInfo, 0x00000001, 0);
64 HW_AVX = (cpuInfo[2] & ((int)1 << 28)) != 0;
70 bool osUsesXSAVE_XRSTORE = (cpuInfo[2] & (1 << 27)) != 0;
71 bool cpuAVXSuport = (cpuInfo[2] & (1 << 28)) != 0;
73 bool avxSupported =
false;
74 if (osUsesXSAVE_XRSTORE && cpuAVXSuport) {
75 uint64_t xcrFeatureMask = xgetbv(_XCR_XFEATURE_ENABLED_MASK);
76 avxSupported = (xcrFeatureMask & 0x6) == 0x6;
78 return HW_AVX && avxSupported;
82 if (!AVXCapable())
return false;
88 int nIds = cpuInfo[0];
90 bool HW_AVX512F =
false;
91 if (nIds >= 0x00000007) {
92 cpuid(cpuInfo, 0x00000007, 0);
93 HW_AVX512F = (cpuInfo[1] & ((int)1 << 16)) != 0;
99 bool osUsesXSAVE_XRSTORE = (cpuInfo[2] & (1 << 27)) != 0;
100 bool cpuAVXSuport = (cpuInfo[2] & (1 << 28)) != 0;
102 bool avx512Supported =
false;
103 if (osUsesXSAVE_XRSTORE && cpuAVXSuport) {
104 uint64_t xcrFeatureMask = xgetbv(_XCR_XFEATURE_ENABLED_MASK);
105 avx512Supported = (xcrFeatureMask & 0xe6) == 0xe6;
107 return HW_AVX512F && avx512Supported;
119 template <
typename T>
123 return p1.first > p2.first;
129 out.write((
char *) &podRef,
sizeof(T));
134 in.read((
char *) &podRef,
sizeof(T));
137 template<
typename MTYPE>
138 using DISTFUNC = MTYPE(*)(
const void *,
const void *,
const void *);
141 template<
typename MTYPE>
154 template<
typename dist_t>
158 virtual std::priority_queue<std::pair<dist_t, labeltype >>
searchKnn(
const void *,
size_t)
const = 0;
161 virtual std::vector<std::pair<dist_t, labeltype>>
169 template<
typename dist_t>
170 std::vector<std::pair<dist_t, labeltype>>
172 std::vector<std::pair<dist_t, labeltype>> result;
175 auto ret = searchKnn(query_data, k);
177 size_t sz = ret.size();
179 while (!ret.empty()) {
180 result[--sz] = ret.top();
virtual ~AlgorithmInterface()
Definition hnswlib.h:165
virtual void saveIndex(const std::string &location)=0
virtual std::vector< std::pair< dist_t, labeltype > > searchKnnCloserFirst(const void *query_data, size_t k) const
Definition hnswlib.h:171
virtual void addPoint(const void *datapoint, labeltype label)=0
virtual std::priority_queue< std::pair< dist_t, labeltype > > searchKnn(const void *, size_t) const =0
virtual size_t get_data_size()=0
virtual ~SpaceInterface()
Definition hnswlib.h:151
virtual void * get_dist_func_param()=0
virtual DISTFUNC< MTYPE > get_dist_func()=0
bool operator()(const T &p1, const T &p2)
Definition hnswlib.h:122
Definition bruteforce.h:7
size_t labeltype
Definition hnswlib.h:117
static void writeBinaryPOD(std::ostream &out, const T &podRef)
Definition hnswlib.h:128
static void readBinaryPOD(std::istream &in, T &podRef)
Definition hnswlib.h:133
MTYPE(*)(const void *, const void *, const void *) DISTFUNC
Definition hnswlib.h:138