mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
added detection & dispatching of some modern NEON instructions (NEON_FP16, NEON_BF16) (#24420)
* added more or less cross-platform (based on POSIX signal() semantics) method to detect various NEON extensions, such as FP16 SIMD arithmetics, BF16 SIMD arithmetics, SIMD dotprod etc. It could be propagated to other instruction sets if necessary. * hopefully fixed compile errors * continue to fix CI * another attempt to fix build on Linux aarch64 * * reverted to the original method to detect special arm neon instructions without signal() * renamed FP16_SIMD & BF16_SIMD to NEON_FP16 and NEON_BF16, respectively * removed extra whitespaces
This commit is contained in:
+25
-11
@@ -408,6 +408,8 @@ struct HWFeatures
|
||||
|
||||
g_hwFeatureNames[CPU_NEON] = "NEON";
|
||||
g_hwFeatureNames[CPU_NEON_DOTPROD] = "NEON_DOTPROD";
|
||||
g_hwFeatureNames[CPU_NEON_FP16] = "NEON_FP16";
|
||||
g_hwFeatureNames[CPU_NEON_BF16] = "NEON_BF16";
|
||||
|
||||
g_hwFeatureNames[CPU_VSX] = "VSX";
|
||||
g_hwFeatureNames[CPU_VSX3] = "VSX3";
|
||||
@@ -566,10 +568,15 @@ struct HWFeatures
|
||||
|
||||
while ((size_t)read(cpufile, &auxv, size_auxv_t) == size_auxv_t)
|
||||
{
|
||||
// see https://elixir.bootlin.com/linux/latest/source/arch/arm64/include/uapi/asm/hwcap.h
|
||||
if (auxv.a_type == AT_HWCAP)
|
||||
{
|
||||
have[CV_CPU_NEON_DOTPROD] = (auxv.a_un.a_val & (1 << 20)) != 0;
|
||||
break;
|
||||
have[CV_CPU_NEON_DOTPROD] = (auxv.a_un.a_val & (1 << 20)) != 0; // HWCAP_ASIMDDP
|
||||
have[CV_CPU_NEON_FP16] = (auxv.a_un.a_val & (1 << 10)) != 0; // HWCAP_ASIMDHP
|
||||
}
|
||||
else if (auxv.a_type == AT_HWCAP2)
|
||||
{
|
||||
have[CV_CPU_NEON_BF16] = (auxv.a_un.a_val & (1 << 14)) != 0; // HWCAP2_BF16
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,16 +630,23 @@ struct HWFeatures
|
||||
have[CV_CPU_NEON] = true;
|
||||
#endif
|
||||
#if (defined __ARM_FP && (((__ARM_FP & 0x2) != 0) && defined __ARM_NEON__))
|
||||
have[CV_CPU_FP16] = true;
|
||||
#endif
|
||||
#if (defined __ARM_FEATURE_DOTPROD)
|
||||
int has_feat_dotprod = 0;
|
||||
size_t has_feat_dotprod_size = sizeof(has_feat_dotprod);
|
||||
sysctlbyname("hw.optional.arm.FEAT_DotProd", &has_feat_dotprod, &has_feat_dotprod_size, NULL, 0);
|
||||
if (has_feat_dotprod) {
|
||||
have[CV_CPU_NEON_DOTPROD] = true;
|
||||
}
|
||||
have[CV_CPU_FP16] = have[CV_CPU_NEON_FP16] = true;
|
||||
#endif
|
||||
// system.cpp may be compiled w/o special -march=armv8...+dotprod, -march=armv8...+bf16 etc.,
|
||||
// so we check for the features in any case, no mater what are the compile flags.
|
||||
// We check the real hardware capabilities here.
|
||||
int has_feat_dotprod = 0;
|
||||
size_t has_feat_dotprod_size = sizeof(has_feat_dotprod);
|
||||
sysctlbyname("hw.optional.arm.FEAT_DotProd", &has_feat_dotprod, &has_feat_dotprod_size, NULL, 0);
|
||||
if (has_feat_dotprod) {
|
||||
have[CV_CPU_NEON_DOTPROD] = true;
|
||||
}
|
||||
int has_feat_bf16 = 0;
|
||||
size_t has_feat_bf16_size = sizeof(has_feat_bf16);
|
||||
sysctlbyname("hw.optional.arm.FEAT_BF16", &has_feat_bf16, &has_feat_bf16_size, NULL, 0);
|
||||
if (has_feat_bf16) {
|
||||
have[CV_CPU_NEON_BF16] = true;
|
||||
}
|
||||
#elif (defined __clang__)
|
||||
#if (defined __ARM_NEON__ || (defined __ARM_NEON && defined __aarch64__))
|
||||
have[CV_CPU_NEON] = true;
|
||||
|
||||
Reference in New Issue
Block a user