feat(core): support cpu flag detect & dispatch (#3)
This commit is contained in:
parent
220a9aba11
commit
1d9791b57a
|
|
@ -416,6 +416,7 @@ const char *CpuFeatures::Intrinsics(void) {
|
|||
;
|
||||
}
|
||||
|
||||
CpuFeatures::StaticFlags CpuFeatures::static_flags_;
|
||||
} // namespace internal
|
||||
} // namespace ailego
|
||||
} // namespace zvec
|
||||
|
|
@ -201,6 +201,169 @@ class CpuFeatures {
|
|||
|
||||
//! Static Members
|
||||
static CpuFlags flags_;
|
||||
|
||||
public:
|
||||
struct StaticFlags {
|
||||
//! 16-bit FP conversions
|
||||
bool F16C = CpuFeatures::F16C();
|
||||
|
||||
//! Multimedia Extensions
|
||||
bool MMX = CpuFeatures::MMX();
|
||||
|
||||
//! Streaming SIMD Extensions
|
||||
bool SSE = CpuFeatures::SSE();
|
||||
|
||||
//! Streaming SIMD Extensions 2
|
||||
bool SSE2 = CpuFeatures::SSE2();
|
||||
|
||||
//! Streaming SIMD Extensions 3
|
||||
bool SSE3 = CpuFeatures::SSE3();
|
||||
|
||||
//! Supplemental Streaming SIMD Extensions 3
|
||||
bool SSSE3 = CpuFeatures::SSSE3();
|
||||
|
||||
//! Streaming SIMD Extensions 4.1
|
||||
bool SSE4_1 = CpuFeatures::SSE4_1();
|
||||
|
||||
//! Streaming SIMD Extensions 4.2
|
||||
bool SSE4_2 = CpuFeatures::SSE4_2();
|
||||
|
||||
//! Advanced Vector Extensions
|
||||
bool AVX = CpuFeatures::AVX();
|
||||
|
||||
//! Advanced Vector Extensions 2
|
||||
bool AVX2 = CpuFeatures::AVX2();
|
||||
|
||||
//! AVX-512 Foundation
|
||||
bool AVX512F = CpuFeatures::AVX512F();
|
||||
|
||||
//! AVX-512 DQ (Double/Quad granular) Instructions
|
||||
bool AVX512DQ = CpuFeatures::AVX512DQ();
|
||||
|
||||
//! AVX-512 Prefetch
|
||||
bool AVX512PF = CpuFeatures::AVX512PF();
|
||||
|
||||
//! AVX-512 Exponential and Reciprocal
|
||||
bool AVX512ER = CpuFeatures::AVX512ER();
|
||||
|
||||
//! AVX-512 Conflict Detection
|
||||
bool AVX512CD = CpuFeatures::AVX512CD();
|
||||
|
||||
//! AVX-512 BW (Byte/Word granular) Instructions
|
||||
bool AVX512BW = CpuFeatures::AVX512BW();
|
||||
|
||||
//! AVX-512 VL (128/256 Vector Length) Extensions
|
||||
bool AVX512VL = CpuFeatures::AVX512VL();
|
||||
|
||||
//! AVX-512 Integer Fused Multiply-Add instructions
|
||||
bool AVX512_IFMA = CpuFeatures::AVX512_IFMA();
|
||||
|
||||
//! AVX512 Vector Bit Manipulation instructions
|
||||
bool AVX512_VBMI = CpuFeatures::AVX512_VBMI();
|
||||
|
||||
//! Additional AVX512 Vector Bit Manipulation Instructions
|
||||
bool AVX512_VBMI2 = CpuFeatures::AVX512_VBMI2();
|
||||
|
||||
//! Vector Neural Network Instructions
|
||||
bool AVX512_VNNI = CpuFeatures::AVX512_VNNI();
|
||||
|
||||
//! Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions
|
||||
bool AVX512_BITALG = CpuFeatures::AVX512_BITALG();
|
||||
|
||||
//! POPCNT for vectors of DW/QW
|
||||
bool AVX512_VPOPCNTDQ = CpuFeatures::AVX512_VPOPCNTDQ();
|
||||
|
||||
//! AVX-512 Neural Network Instructions
|
||||
bool AVX512_4VNNIW = CpuFeatures::AVX512_4VNNIW();
|
||||
|
||||
//! AVX-512 Multiply Accumulation Single precision
|
||||
bool AVX512_4FMAPS = CpuFeatures::AVX512_4FMAPS();
|
||||
|
||||
//! AVX-512 FP16 instructions
|
||||
bool AVX512_FP16 = CpuFeatures::AVX512_FP16();
|
||||
|
||||
//! CMPXCHG8 instruction
|
||||
bool CX8 = CpuFeatures::CX8();
|
||||
|
||||
//! CMPXCHG16B instruction
|
||||
bool CX16 = CpuFeatures::CX16();
|
||||
|
||||
//! PCLMULQDQ instruction
|
||||
bool PCLMULQDQ = CpuFeatures::PCLMULQDQ();
|
||||
|
||||
//! Carry-Less Multiplication Double Quadword
|
||||
bool VPCLMULQDQ = CpuFeatures::VPCLMULQDQ();
|
||||
|
||||
//! CMOV instructions (plus FCMOVcc, FCOMI with FPU)
|
||||
bool CMOV = CpuFeatures::CMOV();
|
||||
|
||||
//! MOVBE instruction
|
||||
bool MOVBE = CpuFeatures::MOVBE();
|
||||
|
||||
//! Enhanced REP MOVSB/STOSB instructions
|
||||
bool ERMS = CpuFeatures::ERMS();
|
||||
|
||||
//! POPCNT instruction
|
||||
bool POPCNT = CpuFeatures::POPCNT();
|
||||
|
||||
//! XSAVE/XRSTOR/XSETBV/XGETBV instructions
|
||||
bool XSAVE = CpuFeatures::XSAVE();
|
||||
|
||||
//! Fused multiply-add
|
||||
bool FMA = CpuFeatures::FMA();
|
||||
|
||||
//! ADCX and ADOX instructions
|
||||
bool ADX = CpuFeatures::ADX();
|
||||
|
||||
//! Galois Field New Instructions
|
||||
bool GFNI = CpuFeatures::GFNI();
|
||||
|
||||
//! AES instructions
|
||||
bool AES = CpuFeatures::AES();
|
||||
|
||||
//! Vector AES
|
||||
bool VAES = CpuFeatures::VAES();
|
||||
|
||||
//! RDSEED instruction
|
||||
bool RDSEED = CpuFeatures::RDSEED();
|
||||
|
||||
//! RDRAND instruction
|
||||
bool RDRAND = CpuFeatures::RDRAND();
|
||||
|
||||
//! SHA1/SHA256 Instruction Extensions
|
||||
bool SHA = CpuFeatures::SHA();
|
||||
|
||||
//! 1st group bit manipulation extensions
|
||||
bool BMI1 = CpuFeatures::BMI1();
|
||||
|
||||
//! 2nd group bit manipulation extensions
|
||||
bool BMI2 = CpuFeatures::BMI2();
|
||||
|
||||
//! CLFLUSH instruction
|
||||
bool CLFLUSH = CpuFeatures::CLFLUSH();
|
||||
|
||||
//! CLFLUSHOPT instruction
|
||||
bool CLFLUSHOPT = CpuFeatures::CLFLUSHOPT();
|
||||
|
||||
//! CLWB instruction
|
||||
bool CLWB = CpuFeatures::CLWB();
|
||||
|
||||
//! RDPID instruction
|
||||
bool RDPID = CpuFeatures::RDPID();
|
||||
|
||||
//! Onboard FPU
|
||||
bool FPU = CpuFeatures::FPU();
|
||||
|
||||
//! Hyper-Threading
|
||||
bool HT = CpuFeatures::HT();
|
||||
|
||||
//! Hardware virtualization
|
||||
bool VMX = CpuFeatures::VMX();
|
||||
|
||||
// !Running on a hypervisor
|
||||
bool HYPERVISOR = CpuFeatures::HYPERVISOR();
|
||||
};
|
||||
static StaticFlags static_flags_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <ailego/internal/platform.h>
|
||||
#include "matrix_define.i"
|
||||
|
||||
#include <iostream>
|
||||
#if !defined(__AVX__)
|
||||
#define _mm_broadcast_si32(a) _mm_castps_si128(_mm_load1_ps((const float *)(a)))
|
||||
#else
|
||||
|
|
@ -95,13 +95,13 @@
|
|||
} \
|
||||
case 1: { \
|
||||
__m256 ymm_lhs = _mm256_cvtph_ps( \
|
||||
_mm_set_epi16((short)(_MASK), (short)(_MASK), (short)(_MASK), \
|
||||
_mm_set_epi16(*((const short *)(lhs)), (short)(_MASK), \
|
||||
(short)(_MASK), (short)(_MASK), (short)(_MASK), \
|
||||
(short)(_MASK), *((const short *)(lhs)))); \
|
||||
(short)(_MASK), (short)(_MASK), (short)(_MASK))); \
|
||||
__m256 ymm_rhs = _mm256_cvtph_ps( \
|
||||
_mm_set_epi16((short)(_MASK), (short)(_MASK), (short)(_MASK), \
|
||||
_mm_set_epi16(*((const short *)(rhs)), (short)(_MASK), \
|
||||
(short)(_MASK), (short)(_MASK), (short)(_MASK), \
|
||||
(short)(_MASK), *((const short *)(rhs)))); \
|
||||
(short)(_MASK), (short)(_MASK), (short)(_MASK))); \
|
||||
_PROC(ymm_lhs, ymm_rhs, _RES##_0_0) \
|
||||
break; \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -178,14 +178,15 @@ struct SquaredEuclideanDistanceMatrix<
|
|||
protected:
|
||||
//! Calculate the squared difference
|
||||
static inline float SquaredDifference(uint32_t lhs, uint32_t rhs) {
|
||||
return static_cast<float>(MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 0), (int8_t)(rhs >> 0)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 8), (int8_t)(rhs >> 8)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 16), (int8_t)(rhs >> 16)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 24), (int8_t)(rhs >> 24)));
|
||||
volatile int32_t sum = MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 0), (int8_t)(rhs >> 0)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 8), (int8_t)(rhs >> 8)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 16), (int8_t)(rhs >> 16)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 24), (int8_t)(rhs >> 24));
|
||||
return static_cast<float>(sum);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -228,14 +229,15 @@ struct SquaredEuclideanDistanceMatrix<int8_t, M, 1,
|
|||
protected:
|
||||
//! Calculate the squared difference
|
||||
static inline float SquaredDifference(uint32_t lhs, uint32_t rhs) {
|
||||
return static_cast<float>(MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 0), (int8_t)(rhs >> 0)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 8), (int8_t)(rhs >> 8)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 16), (int8_t)(rhs >> 16)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 24), (int8_t)(rhs >> 24)));
|
||||
volatile int32_t sum = MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 0), (int8_t)(rhs >> 0)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 8), (int8_t)(rhs >> 8)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 16), (int8_t)(rhs >> 16)) +
|
||||
MathHelper::SquaredDifference<int8_t, int32_t>(
|
||||
(int8_t)(lhs >> 24), (int8_t)(rhs >> 24));
|
||||
return static_cast<float>(sum);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <ailego/internal/cpu_features.h>
|
||||
#include "distance_matrix_accum_fp16.i"
|
||||
#include "euclidean_distance_matrix.h"
|
||||
|
||||
|
|
@ -131,6 +132,7 @@ static inline float SquaredEuclideanDistanceAVX512FP16(const Float16 *lhs,
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=1, N=1)
|
||||
void SquaredEuclideanDistanceMatrix<Float16, 1, 1>::Compute(const ValueType *m,
|
||||
const ValueType *q,
|
||||
|
|
@ -138,13 +140,21 @@ void SquaredEuclideanDistanceMatrix<Float16, 1, 1>::Compute(const ValueType *m,
|
|||
float *out) {
|
||||
#if defined(__ARM_NEON)
|
||||
ACCUM_FP16_1X1_NEON(m, q, dim, out, 0ull, )
|
||||
#elif defined(__AVX512FP16__)
|
||||
*out = SquaredEuclideanDistanceAVX512FP16(m, q, dim);
|
||||
#elif defined(__AVX512F__)
|
||||
ACCUM_FP16_1X1_AVX512(m, q, dim, out, 0ull, )
|
||||
#else
|
||||
#if defined(__AVX512FP16__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512_FP16) {
|
||||
*out = SquaredEuclideanDistanceAVX512FP16(m, q, dim);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(__AVX512F__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_1X1_AVX512(m, q, dim, out, 0ull, )
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ACCUM_FP16_1X1_AVX(m, q, dim, out, 0ull, )
|
||||
#endif // __AVX512F__
|
||||
#endif //__ARM_NEON
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=1, N=1)
|
||||
|
|
@ -153,13 +163,21 @@ void EuclideanDistanceMatrix<Float16, 1, 1>::Compute(const ValueType *m,
|
|||
size_t dim, float *out) {
|
||||
#if defined(__ARM_NEON)
|
||||
ACCUM_FP16_1X1_NEON(m, q, dim, out, 0ull, std::sqrt)
|
||||
#elif defined(__AVX512FP16__)
|
||||
*out = std::sqrt(SquaredEuclideanDistanceAVX512FP16(m, q, dim));
|
||||
#elif defined(__AVX512F__)
|
||||
ACCUM_FP16_1X1_AVX512(m, q, dim, out, 0ull, std::sqrt)
|
||||
#else
|
||||
#if defined(__AVX512FP16__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512_FP16) {
|
||||
*out = std::sqrt(SquaredEuclideanDistanceAVX512FP16(m, q, dim));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(__AVX512F__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_1X1_AVX512(m, q, dim, out, 0ull, std::sqrt)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ACCUM_FP16_1X1_AVX(m, q, dim, out, 0ull, std::sqrt)
|
||||
#endif // __AVX512F__
|
||||
#endif //__ARM_NEON
|
||||
}
|
||||
|
||||
#if !defined(__ARM_NEON)
|
||||
|
|
@ -241,10 +259,13 @@ void SquaredEuclideanDistanceMatrix<Float16, 16, 1>::Compute(const ValueType *m,
|
|||
size_t dim,
|
||||
float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X1_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_16X1_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X1_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
|
||||
ACCUM_FP16_16X1_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=16, N=2)
|
||||
|
|
@ -253,10 +274,13 @@ void SquaredEuclideanDistanceMatrix<Float16, 16, 2>::Compute(const ValueType *m,
|
|||
size_t dim,
|
||||
float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X2_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_16X2_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X2_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
|
||||
ACCUM_FP16_16X2_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=16, N=4)
|
||||
|
|
@ -265,10 +289,12 @@ void SquaredEuclideanDistanceMatrix<Float16, 16, 4>::Compute(const ValueType *m,
|
|||
size_t dim,
|
||||
float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X4_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_16X4_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X4_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_16X4_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=16, N=8)
|
||||
|
|
@ -277,20 +303,24 @@ void SquaredEuclideanDistanceMatrix<Float16, 16, 8>::Compute(const ValueType *m,
|
|||
size_t dim,
|
||||
float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X8_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_16X8_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X8_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_16X8_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=16, N=16)
|
||||
void SquaredEuclideanDistanceMatrix<Float16, 16, 16>::Compute(
|
||||
const ValueType *m, const ValueType *q, size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X16_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_16X16_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X16_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_16X16_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=1)
|
||||
|
|
@ -299,10 +329,12 @@ void SquaredEuclideanDistanceMatrix<Float16, 32, 1>::Compute(const ValueType *m,
|
|||
size_t dim,
|
||||
float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X1_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_32X1_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X1_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X1_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=2)
|
||||
|
|
@ -311,10 +343,12 @@ void SquaredEuclideanDistanceMatrix<Float16, 32, 2>::Compute(const ValueType *m,
|
|||
size_t dim,
|
||||
float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X2_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_32X2_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X2_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X2_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=4)
|
||||
|
|
@ -323,10 +357,12 @@ void SquaredEuclideanDistanceMatrix<Float16, 32, 4>::Compute(const ValueType *m,
|
|||
size_t dim,
|
||||
float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X4_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_32X4_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X4_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X4_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=8)
|
||||
|
|
@ -335,30 +371,36 @@ void SquaredEuclideanDistanceMatrix<Float16, 32, 8>::Compute(const ValueType *m,
|
|||
size_t dim,
|
||||
float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X8_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_32X8_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X8_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X8_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=16)
|
||||
void SquaredEuclideanDistanceMatrix<Float16, 32, 16>::Compute(
|
||||
const ValueType *m, const ValueType *q, size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X16_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_32X16_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X16_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X16_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=32)
|
||||
void SquaredEuclideanDistanceMatrix<Float16, 32, 32>::Compute(
|
||||
const ValueType *m, const ValueType *q, size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X32_AVX512(m, q, dim, out, )
|
||||
#else
|
||||
ACCUM_FP16_32X32_AVX(m, q, dim, out, )
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X32_AVX512(m, q, dim, out, )
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X32_AVX(m, q, dim, out, )
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=2, N=1)
|
||||
|
|
@ -429,10 +471,12 @@ void EuclideanDistanceMatrix<Float16, 16, 1>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X1_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_16X1_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X1_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_16X1_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=16, N=2)
|
||||
|
|
@ -440,10 +484,12 @@ void EuclideanDistanceMatrix<Float16, 16, 2>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X2_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_16X2_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X2_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_16X2_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=16, N=4)
|
||||
|
|
@ -451,10 +497,12 @@ void EuclideanDistanceMatrix<Float16, 16, 4>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X4_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_16X4_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X4_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_16X4_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=16, N=8)
|
||||
|
|
@ -462,10 +510,12 @@ void EuclideanDistanceMatrix<Float16, 16, 8>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X8_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_16X8_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X8_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_16X8_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=16, N=16)
|
||||
|
|
@ -473,10 +523,12 @@ void EuclideanDistanceMatrix<Float16, 16, 16>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_16X16_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_16X16_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_16X16_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_16X16_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=1)
|
||||
|
|
@ -484,10 +536,12 @@ void EuclideanDistanceMatrix<Float16, 32, 1>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X1_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_32X1_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X1_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X1_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=2)
|
||||
|
|
@ -495,10 +549,12 @@ void EuclideanDistanceMatrix<Float16, 32, 2>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X2_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_32X2_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X2_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X2_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=4)
|
||||
|
|
@ -506,10 +562,12 @@ void EuclideanDistanceMatrix<Float16, 32, 4>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X4_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_32X4_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X4_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X4_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=8)
|
||||
|
|
@ -517,10 +575,12 @@ void EuclideanDistanceMatrix<Float16, 32, 8>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X8_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_32X8_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X8_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X8_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=16)
|
||||
|
|
@ -528,10 +588,12 @@ void EuclideanDistanceMatrix<Float16, 32, 16>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X16_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_32X16_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X16_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X16_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=32, N=32)
|
||||
|
|
@ -539,10 +601,12 @@ void EuclideanDistanceMatrix<Float16, 32, 32>::Compute(const ValueType *m,
|
|||
const ValueType *q,
|
||||
size_t dim, float *out) {
|
||||
#if defined(__AVX512F__)
|
||||
ACCUM_FP16_32X32_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
#else
|
||||
ACCUM_FP16_32X32_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_32X32_AVX512(m, q, dim, out, _mm512_sqrt_ps)
|
||||
return;
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
ACCUM_FP16_32X32_AVX(m, q, dim, out, _mm256_sqrt_ps)
|
||||
}
|
||||
#endif // !__ARM_NEON
|
||||
#endif // (__F16C__ && __AVX__) || (__ARM_NEON && __aarch64__)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <ailego/internal/cpu_features.h>
|
||||
#include "distance_matrix_accum_fp32.i"
|
||||
#include "euclidean_distance_matrix.h"
|
||||
|
||||
|
|
@ -291,15 +292,19 @@ void SquaredEuclideanDistanceMatrix<float, 1, 1>::Compute(const ValueType *m,
|
|||
*out = SquaredEuclideanDistanceNEON(m, q, dim);
|
||||
#else
|
||||
#if defined(__AVX512F__)
|
||||
if (dim > 15) {
|
||||
*out = SquaredEuclideanDistanceAVX512(m, q, dim);
|
||||
return;
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
if (dim > 15) {
|
||||
*out = SquaredEuclideanDistanceAVX512(m, q, dim);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
#if defined(__AVX__)
|
||||
if (dim > 7) {
|
||||
*out = SquaredEuclideanDistanceAVX(m, q, dim);
|
||||
return;
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX) {
|
||||
if (dim > 7) {
|
||||
*out = SquaredEuclideanDistanceAVX(m, q, dim);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // __AVX__
|
||||
*out = SquaredEuclideanDistanceSSE(m, q, dim);
|
||||
|
|
@ -618,15 +623,20 @@ void EuclideanDistanceMatrix<float, 1, 1>::Compute(const ValueType *m,
|
|||
*out = std::sqrt(SquaredEuclideanDistanceNEON(m, q, dim));
|
||||
#else
|
||||
#if defined(__AVX512F__)
|
||||
if (dim > 15) {
|
||||
*out = std::sqrt(SquaredEuclideanDistanceAVX512(m, q, dim));
|
||||
return;
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
if (dim > 15) {
|
||||
*out = std::sqrt(SquaredEuclideanDistanceAVX512(m, q, dim));
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
|
||||
#if defined(__AVX__)
|
||||
if (dim > 7) {
|
||||
*out = std::sqrt(SquaredEuclideanDistanceAVX(m, q, dim));
|
||||
return;
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX) {
|
||||
if (dim > 7) {
|
||||
*out = std::sqrt(SquaredEuclideanDistanceAVX(m, q, dim));
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // __AVX__
|
||||
*out = std::sqrt(SquaredEuclideanDistanceSSE(m, q, dim));
|
||||
|
|
|
|||
|
|
@ -181,10 +181,12 @@ struct InnerProductMatrix<int8_t, M, N,
|
|||
protected:
|
||||
//! Calculate Fused-Multiply-Add
|
||||
static inline float FusedMultiplyAdd(uint32_t lhs, uint32_t rhs) {
|
||||
return static_cast<float>((int8_t)(lhs >> 0) * (int8_t)(rhs >> 0) +
|
||||
(int8_t)(lhs >> 8) * (int8_t)(rhs >> 8) +
|
||||
(int8_t)(lhs >> 16) * (int8_t)(rhs >> 16) +
|
||||
(int8_t)(lhs >> 24) * (int8_t)(rhs >> 24));
|
||||
volatile int32_t sum = ((int8_t)(lhs >> 0) * (int8_t)(rhs >> 0) +
|
||||
(int8_t)(lhs >> 8) * (int8_t)(rhs >> 8) +
|
||||
(int8_t)(lhs >> 16) * (int8_t)(rhs >> 16) +
|
||||
(int8_t)(lhs >> 24) * (int8_t)(rhs >> 24));
|
||||
|
||||
return static_cast<float>(sum);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -226,10 +228,12 @@ struct InnerProductMatrix<int8_t, M, 1, typename std::enable_if<M >= 2>::type> {
|
|||
protected:
|
||||
//! Calculate Fused-Multiply-Add
|
||||
static inline float FusedMultiplyAdd(uint32_t lhs, uint32_t rhs) {
|
||||
return static_cast<float>((int8_t)(lhs >> 0) * (int8_t)(rhs >> 0) +
|
||||
(int8_t)(lhs >> 8) * (int8_t)(rhs >> 8) +
|
||||
(int8_t)(lhs >> 16) * (int8_t)(rhs >> 16) +
|
||||
(int8_t)(lhs >> 24) * (int8_t)(rhs >> 24));
|
||||
volatile int32_t sum = ((int8_t)(lhs >> 0) * (int8_t)(rhs >> 0) +
|
||||
(int8_t)(lhs >> 8) * (int8_t)(rhs >> 8) +
|
||||
(int8_t)(lhs >> 16) * (int8_t)(rhs >> 16) +
|
||||
(int8_t)(lhs >> 24) * (int8_t)(rhs >> 24));
|
||||
|
||||
return static_cast<float>(sum);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -524,10 +528,12 @@ struct MinusInnerProductMatrix<
|
|||
protected:
|
||||
//! Calculate Fused-Multiply-Add
|
||||
static inline float FusedMultiplyAdd(uint32_t lhs, uint32_t rhs) {
|
||||
return static_cast<float>((int8_t)(lhs >> 0) * (int8_t)(rhs >> 0) +
|
||||
(int8_t)(lhs >> 8) * (int8_t)(rhs >> 8) +
|
||||
(int8_t)(lhs >> 16) * (int8_t)(rhs >> 16) +
|
||||
(int8_t)(lhs >> 24) * (int8_t)(rhs >> 24));
|
||||
volatile int32_t sum = ((int8_t)(lhs >> 0) * (int8_t)(rhs >> 0) +
|
||||
(int8_t)(lhs >> 8) * (int8_t)(rhs >> 8) +
|
||||
(int8_t)(lhs >> 16) * (int8_t)(rhs >> 16) +
|
||||
(int8_t)(lhs >> 24) * (int8_t)(rhs >> 24));
|
||||
|
||||
return static_cast<float>(sum);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -570,10 +576,12 @@ struct MinusInnerProductMatrix<int8_t, M, 1,
|
|||
protected:
|
||||
//! Calculate Fused-Multiply-Add
|
||||
static inline float FusedMultiplyAdd(uint32_t lhs, uint32_t rhs) {
|
||||
return static_cast<float>((int8_t)(lhs >> 0) * (int8_t)(rhs >> 0) +
|
||||
(int8_t)(lhs >> 8) * (int8_t)(rhs >> 8) +
|
||||
(int8_t)(lhs >> 16) * (int8_t)(rhs >> 16) +
|
||||
(int8_t)(lhs >> 24) * (int8_t)(rhs >> 24));
|
||||
volatile int32_t sum = ((int8_t)(lhs >> 0) * (int8_t)(rhs >> 0) +
|
||||
(int8_t)(lhs >> 8) * (int8_t)(rhs >> 8) +
|
||||
(int8_t)(lhs >> 16) * (int8_t)(rhs >> 16) +
|
||||
(int8_t)(lhs >> 24) * (int8_t)(rhs >> 24));
|
||||
|
||||
return static_cast<float>(sum);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <ailego/internal/cpu_features.h>
|
||||
#include "distance_matrix_accum_fp16.i"
|
||||
#include "inner_product_matrix.h"
|
||||
|
||||
|
|
@ -144,13 +145,21 @@ void InnerProductMatrix<Float16, 1, 1>::Compute(const ValueType *m,
|
|||
float *out) {
|
||||
#if defined(__ARM_NEON)
|
||||
ACCUM_FP16_1X1_NEON(m, q, dim, out, 0ull, )
|
||||
#elif defined(__AVX512FP16__)
|
||||
*out = InnerProductAVX512FP16(m, q, dim);
|
||||
#elif defined(__AVX512F__)
|
||||
ACCUM_FP16_1X1_AVX512(m, q, dim, out, 0ull, )
|
||||
#else
|
||||
#if defined(__AVX512FP16__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512_FP16) {
|
||||
*out = InnerProductAVX512FP16(m, q, dim);
|
||||
return;
|
||||
}
|
||||
#endif //__AVX512FP16__
|
||||
#if defined(__AVX512F__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_1X1_AVX512(m, q, dim, out, 0ull, )
|
||||
return;
|
||||
}
|
||||
#endif //__AVX512F__
|
||||
ACCUM_FP16_1X1_AVX(m, q, dim, out, 0ull, )
|
||||
#endif
|
||||
#endif //__ARM_NEON
|
||||
}
|
||||
|
||||
//! Compute the distance between matrix and query (FP16, M=1, N=1)
|
||||
|
|
@ -159,13 +168,21 @@ void MinusInnerProductMatrix<Float16, 1, 1>::Compute(const ValueType *m,
|
|||
size_t dim, float *out) {
|
||||
#if defined(__ARM_NEON)
|
||||
ACCUM_FP16_1X1_NEON(m, q, dim, out, 0ull, NEGATE_FP32_GENERAL)
|
||||
#elif defined(__AVX512FP16__)
|
||||
*out = -InnerProductAVX512FP16(m, q, dim);
|
||||
#elif defined(__AVX512F__)
|
||||
ACCUM_FP16_1X1_AVX512(m, q, dim, out, 0ull, NEGATE_FP32_GENERAL)
|
||||
#else
|
||||
#if defined(__AVX512FP16__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512_FP16) {
|
||||
*out = -InnerProductAVX512FP16(m, q, dim);
|
||||
return;
|
||||
}
|
||||
#endif //__AVX512FP16__
|
||||
#if defined(__AVX512F__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
ACCUM_FP16_1X1_AVX512(m, q, dim, out, 0ull, NEGATE_FP32_GENERAL)
|
||||
return;
|
||||
}
|
||||
#endif //__AVX512F__
|
||||
ACCUM_FP16_1X1_AVX(m, q, dim, out, 0ull, NEGATE_FP32_GENERAL)
|
||||
#endif
|
||||
#endif //__ARM_NEON
|
||||
}
|
||||
|
||||
#if !defined(__ARM_NEON)
|
||||
|
|
|
|||
|
|
@ -12,30 +12,10 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <ailego/internal/cpu_features.h>
|
||||
#include "distance_matrix_accum_fp32.i"
|
||||
#include "inner_product_matrix.h"
|
||||
|
||||
#if DEBUG_PRINT
|
||||
#include <iostream>
|
||||
|
||||
static void inline print_data16(__m128i *data) {
|
||||
uint16_t buffer[16];
|
||||
|
||||
memcpy(buffer, data, sizeof(buffer));
|
||||
|
||||
// std::cout << "result equals: " << std::endl;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint64_t value = buffer[i];
|
||||
if (i < 8) {
|
||||
std::cout << value << ", ";
|
||||
} else {
|
||||
std::cout << value << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace zvec {
|
||||
namespace ailego {
|
||||
|
||||
|
|
@ -585,15 +565,19 @@ void InnerProductMatrix<float, 1, 1>::Compute(const ValueType *m,
|
|||
*out = InnerProductNEON(m, q, dim);
|
||||
#else
|
||||
#if defined(__AVX512F__)
|
||||
if (dim > 15) {
|
||||
*out = InnerProductAVX512(m, q, dim);
|
||||
return;
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
if (dim > 15) {
|
||||
*out = InnerProductAVX512(m, q, dim);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
#if defined(__AVX__)
|
||||
if (dim > 7) {
|
||||
*out = InnerProductAVX(m, q, dim);
|
||||
return;
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX) {
|
||||
if (dim > 7) {
|
||||
*out = InnerProductAVX(m, q, dim);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // __AVX__
|
||||
*out = InnerProductSSE(m, q, dim);
|
||||
|
|
@ -890,15 +874,19 @@ void MinusInnerProductMatrix<float, 1, 1>::Compute(const ValueType *m,
|
|||
*out = -InnerProductNEON(m, q, dim);
|
||||
#else
|
||||
#if defined(__AVX512F__)
|
||||
if (dim > 15) {
|
||||
*out = -InnerProductAVX512(m, q, dim);
|
||||
return;
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
if (dim > 15) {
|
||||
*out = -InnerProductAVX512(m, q, dim);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // __AVX512F__
|
||||
#if defined(__AVX__)
|
||||
if (dim > 7) {
|
||||
*out = -InnerProductAVX(m, q, dim);
|
||||
return;
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX) {
|
||||
if (dim > 7) {
|
||||
*out = -InnerProductAVX(m, q, dim);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // __AVX__
|
||||
*out = -InnerProductSSE(m, q, dim);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <ailego/internal/cpu_features.h>
|
||||
#include "distance_matrix_accum_int4.i"
|
||||
#include "inner_product_matrix.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <ailego/internal/cpu_features.h>
|
||||
#include <ailego/internal/platform.h>
|
||||
#include <ailego/utility/math_helper.h>
|
||||
#include <ailego/utility/type_helper.h>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <ailego/internal/cpu_features.h>
|
||||
#include <ailego/internal/platform.h>
|
||||
#include <ailego/utility/math_helper.h>
|
||||
#include <ailego/utility/type_helper.h>
|
||||
|
|
@ -75,19 +76,25 @@ struct InnerProductDistanceBatchImpl<int8_t, BatchSize> {
|
|||
// return compute_one_to_many_avx512_int8<ValueType, BatchSize>(
|
||||
// query, ptrs, prefetch_ptrs, dim, sums);
|
||||
#if defined(__AVX512VNNI__)
|
||||
return compute_one_to_many_avx512_vnni_int8<BatchSize>(
|
||||
query, ptrs, prefetch_ptrs, dim, sums);
|
||||
#elif defined(__AVX2__)
|
||||
return compute_one_to_many_avx2_int8<ValueType, BatchSize>(
|
||||
query, ptrs, prefetch_ptrs, dim, sums);
|
||||
#else
|
||||
return compute_one_to_many_fallback(query, ptrs, prefetch_ptrs, dim, sums);
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512_VNNI) {
|
||||
return compute_one_to_many_avx512_vnni_int8<BatchSize>(
|
||||
query, ptrs, prefetch_ptrs, dim, sums);
|
||||
}
|
||||
#endif
|
||||
#if defined(__AVX2__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX2) {
|
||||
return compute_one_to_many_avx2_int8<ValueType, BatchSize>(
|
||||
query, ptrs, prefetch_ptrs, dim, sums);
|
||||
}
|
||||
#endif
|
||||
return compute_one_to_many_fallback(query, ptrs, prefetch_ptrs, dim, sums);
|
||||
}
|
||||
|
||||
static DistanceBatchQueryPreprocessFunc GetQueryPreprocessFunc() {
|
||||
#if defined(__AVX512VNNI__)
|
||||
return compute_one_to_many_avx512_vnni_int8_query_preprocess;
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512_VNNI) {
|
||||
return compute_one_to_many_avx512_vnni_int8_query_preprocess;
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -107,11 +114,24 @@ struct InnerProductDistanceBatchImpl<ailego::Float16, BatchSize> {
|
|||
return compute_one_to_many_avx512f_fp16<ValueType, BatchSize>(
|
||||
query, ptrs, prefetch_ptrs, dim, sums);
|
||||
#elif defined(__AVX2__)
|
||||
return compute_one_to_many_avx_fp16<ValueType, BatchSize>(
|
||||
return compute_one_to_many_avx2_fp16<ValueType, BatchSize>(
|
||||
query, ptrs, prefetch_ptrs, dim, sums);
|
||||
#else
|
||||
return compute_one_to_many_fallback(query, ptrs, prefetch_ptrs, dim, sums);
|
||||
#endif
|
||||
#if defined(__AVX512F__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX512F) {
|
||||
return compute_one_to_many_avx512f_fp16<ValueType, BatchSize>(
|
||||
query, ptrs, prefetch_ptrs, dim, sums);
|
||||
}
|
||||
#endif
|
||||
#if defined(__AVX2__)
|
||||
if (zvec::ailego::internal::CpuFeatures::static_flags_.AVX2) {
|
||||
return compute_one_to_many_avx2_fp16<ValueType, BatchSize>(
|
||||
query, ptrs, prefetch_ptrs, dim, sums);
|
||||
}
|
||||
#endif
|
||||
return compute_one_to_many_fallback(query, ptrs, prefetch_ptrs, dim, sums);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -148,4 +168,4 @@ struct InnerProductDistanceBatch {
|
|||
}
|
||||
};
|
||||
|
||||
} // namespace zvec::ailego::DistanceBatch
|
||||
} // namespace zvec::ailego::DistanceBatch
|
||||
|
|
|
|||
|
|
@ -76,7 +76,9 @@ compute_one_to_many_avx512fp16_fp16(
|
|||
}
|
||||
}
|
||||
|
||||
#elif defined(__AVX512F__)
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512F__)
|
||||
|
||||
template <typename ValueType, size_t dp_batch>
|
||||
static std::enable_if_t<std::is_same_v<ValueType, ailego::Float16>, void>
|
||||
|
|
@ -164,12 +166,13 @@ compute_one_to_many_avx512f_fp16(
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(__AVX2__)
|
||||
#if defined(__AVX2__)
|
||||
|
||||
template <typename ValueType, size_t dp_batch>
|
||||
static std::enable_if_t<std::is_same_v<ValueType, ailego::Float16>, void>
|
||||
compute_one_to_many_av2_fp16(
|
||||
compute_one_to_many_avx2_fp16(
|
||||
const ailego::Float16 *query, const ailego::Float16 **ptrs,
|
||||
std::array<const ailego::Float16 *, dp_batch> &prefetch_ptrs,
|
||||
size_t dimensionality, float *results) {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
namespace zvec::ailego::DistanceBatch {
|
||||
|
||||
|
||||
#if defined(__AVX512VNNI__)
|
||||
|
||||
static void compute_one_to_many_avx512_vnni_int8_query_preprocess(void *query,
|
||||
|
|
@ -154,8 +153,9 @@ static void compute_one_to_many_avx512_vnni_int8(
|
|||
// results[i] = static_cast<float>(temp_results[i]);
|
||||
// }
|
||||
// }
|
||||
#endif
|
||||
|
||||
#elif defined(__AVX2__)
|
||||
#if defined(__AVX2__)
|
||||
|
||||
template <typename ValueType, size_t dp_batch>
|
||||
static std::enable_if_t<std::is_same_v<ValueType, int8_t>, void>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -176,3 +176,111 @@ TEST(CpuFeatures, General) {
|
|||
EXPECT_TRUE(CpuFeatures::MMX());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TEST(CpuFeatures, Static) {
|
||||
std::cout << "* F16C: " << CpuFeatures::static_flags_.F16C
|
||||
<< std::endl;
|
||||
std::cout << "* SSE: " << CpuFeatures::static_flags_.SSE
|
||||
<< std::endl;
|
||||
std::cout << "* SSE2: " << CpuFeatures::static_flags_.SSE2
|
||||
<< std::endl;
|
||||
std::cout << "* SSE3: " << CpuFeatures::static_flags_.SSE3
|
||||
<< std::endl;
|
||||
std::cout << "* SSSE3: " << CpuFeatures::static_flags_.SSSE3
|
||||
<< std::endl;
|
||||
std::cout << "* SSE4_1: " << CpuFeatures::static_flags_.SSE4_1
|
||||
<< std::endl;
|
||||
std::cout << "* SSE4_2: " << CpuFeatures::static_flags_.SSE4_2
|
||||
<< std::endl;
|
||||
std::cout << "* AVX: " << CpuFeatures::static_flags_.AVX
|
||||
<< std::endl;
|
||||
std::cout << "* AVX2: " << CpuFeatures::static_flags_.AVX2
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512F: " << CpuFeatures::static_flags_.AVX512F
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512DQ: " << CpuFeatures::static_flags_.AVX512DQ
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512PF: " << CpuFeatures::static_flags_.AVX512PF
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512ER: " << CpuFeatures::static_flags_.AVX512ER
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512CD: " << CpuFeatures::static_flags_.AVX512CD
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512BW: " << CpuFeatures::static_flags_.AVX512BW
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512VL: " << CpuFeatures::static_flags_.AVX512VL
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512_IFMA: " << CpuFeatures::static_flags_.AVX512_IFMA
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512_VBMI: " << CpuFeatures::static_flags_.AVX512_VBMI
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512_VBMI2: " << CpuFeatures::static_flags_.AVX512_VBMI2
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512_VNNI: " << CpuFeatures::static_flags_.AVX512_VNNI
|
||||
<< std::endl;
|
||||
std::cout << "* AVX512_BITALG: "
|
||||
<< CpuFeatures::static_flags_.AVX512_BITALG << std::endl;
|
||||
std::cout << "* AVX512_VPOPCNTDQ: "
|
||||
<< CpuFeatures::static_flags_.AVX512_VPOPCNTDQ << std::endl;
|
||||
std::cout << "* AVX512_4VNNIW: "
|
||||
<< CpuFeatures::static_flags_.AVX512_4VNNIW << std::endl;
|
||||
std::cout << "* AVX512_4FMAPS: "
|
||||
<< CpuFeatures::static_flags_.AVX512_4FMAPS << std::endl;
|
||||
std::cout << "* AVX512_FP16: " << CpuFeatures::static_flags_.AVX512_FP16
|
||||
<< std::endl;
|
||||
std::cout << "* CX8: " << CpuFeatures::static_flags_.CX8
|
||||
<< std::endl;
|
||||
std::cout << "* CX16: " << CpuFeatures::static_flags_.CX16
|
||||
<< std::endl;
|
||||
std::cout << "* PCLMULQDQ: " << CpuFeatures::static_flags_.PCLMULQDQ
|
||||
<< std::endl;
|
||||
std::cout << "* VPCLMULQDQ: " << CpuFeatures::static_flags_.VPCLMULQDQ
|
||||
<< std::endl;
|
||||
std::cout << "* CMOV: " << CpuFeatures::static_flags_.CMOV
|
||||
<< std::endl;
|
||||
std::cout << "* MOVBE: " << CpuFeatures::static_flags_.MOVBE
|
||||
<< std::endl;
|
||||
std::cout << "* ERMS: " << CpuFeatures::static_flags_.ERMS
|
||||
<< std::endl;
|
||||
std::cout << "* POPCNT: " << CpuFeatures::static_flags_.POPCNT
|
||||
<< std::endl;
|
||||
std::cout << "* XSAVE: " << CpuFeatures::static_flags_.XSAVE
|
||||
<< std::endl;
|
||||
std::cout << "* FMA: " << CpuFeatures::static_flags_.FMA
|
||||
<< std::endl;
|
||||
std::cout << "* ADX: " << CpuFeatures::static_flags_.ADX
|
||||
<< std::endl;
|
||||
std::cout << "* GFNI: " << CpuFeatures::static_flags_.GFNI
|
||||
<< std::endl;
|
||||
std::cout << "* AES: " << CpuFeatures::static_flags_.AES
|
||||
<< std::endl;
|
||||
std::cout << "* VAES: " << CpuFeatures::static_flags_.VAES
|
||||
<< std::endl;
|
||||
std::cout << "* RDSEED: " << CpuFeatures::static_flags_.RDSEED
|
||||
<< std::endl;
|
||||
std::cout << "* RDRAND: " << CpuFeatures::static_flags_.RDRAND
|
||||
<< std::endl;
|
||||
std::cout << "* SHA: " << CpuFeatures::static_flags_.SHA
|
||||
<< std::endl;
|
||||
std::cout << "* BMI1: " << CpuFeatures::static_flags_.BMI1
|
||||
<< std::endl;
|
||||
std::cout << "* BMI2: " << CpuFeatures::static_flags_.BMI2
|
||||
<< std::endl;
|
||||
std::cout << "* CLFLUSH: " << CpuFeatures::static_flags_.CLFLUSH
|
||||
<< std::endl;
|
||||
std::cout << "* CLFLUSHOPT: " << CpuFeatures::static_flags_.CLFLUSHOPT
|
||||
<< std::endl;
|
||||
std::cout << "* CLWB: " << CpuFeatures::static_flags_.CLWB
|
||||
<< std::endl;
|
||||
std::cout << "* RDPID: " << CpuFeatures::static_flags_.RDPID
|
||||
<< std::endl;
|
||||
std::cout << "* FPU: " << CpuFeatures::static_flags_.FPU
|
||||
<< std::endl;
|
||||
std::cout << "* HT: " << CpuFeatures::static_flags_.HT
|
||||
<< std::endl;
|
||||
std::cout << "* VMX: " << CpuFeatures::static_flags_.VMX
|
||||
<< std::endl;
|
||||
std::cout << "* HYPERVISOR: " << CpuFeatures::static_flags_.HYPERVISOR
|
||||
<< std::endl;
|
||||
}
|
||||
Loading…
Reference in New Issue