#include "StgSharpNative.h" #include "sn_intrinsic.h" #if defined(_MSC_VER) && !defined(__clang__) #include #include #else #include #endif // _MSC_VER PRIVATE void load_intrinsic_sse(sn_intrinsic *context); PRIVATE void load_intrinsic_avx(sn_intrinsic *context); PRIVATE void load_intrinsic_512(sn_intrinsic *context); PRIVATE int check_isa(most_advanced_instruction instruction_family) { if (instruction_family != NEON) { #if defined(_MSC_VER) && !defined(__clang__) return __check_isa_support(instruction_family, 0); #else switch (instruction_family) { case SSE: return __builtin_cpu_supports("sse4.2"); case AVX256: return __builtin_cpu_supports("avx2"); case AVX512: return __builtin_cpu_supports("avx512f"); default: return 0; } #endif // _MSC_VER } #if defined(__ARM_NEON) || defined(__ARM_NEON__) return 1; #else return 0; #endif } SN_API int load_intrinsic_function(void *intrinsic_context) { sn_null_assert(intrinsic_context); sn_intrinsic *context = (sn_intrinsic *)intrinsic_context; if (check_isa(AVX512)) { load_intrinsic_512(context); return 3; } else if (check_isa(AVX256)) { load_intrinsic_avx(context); return 2; } else if (check_isa(SSE)) { load_intrinsic_sse(context); return 1; } else if (check_isa(NEON)) { return -1; } return 0; } void load_intrinsic_sse(sn_intrinsic *context) { context->city_hash_simplify = city_hash_simplify_sse; context->factorial_simd = factorial_simd_sse; context->index_pair = index_pair_sse; context->mat_f32_buffer_add = BUF_PROC(float, sse, add); context->mat_f32_buffer_fill = BUF_PROC(float, sse, fill); context->mat_f32_buffer_scalar_mul = BUF_PROC(float, sse, scalar_mul); context->mat_f32_buffer_sub = BUF_PROC(float, sse, sub); context->mat_f32_buffer_transpose = KER_PROC(float, sse, transpose); context->mat_f32_build_panel = NULL; context->mat_f32_clear_panel = PNL_PROC(float, sse, clear); context->mat_f32_panel_fma = PNL_PROC(float, sse, fma); context->mat_f32_pivot = pivot_float; context->mat_f32_store_panel = NULL; context->mat_f64_buffer_add = BUF_PROC(double, sse, add); context->mat_f64_buffer_fill = BUF_PROC(double, sse, fill); context->mat_f64_buffer_scalar_mul = BUF_PROC(double, sse, scalar_mul); context->mat_f64_buffer_sub = BUF_PROC(double, sse, sub); context->mat_f64_buffer_transpose = NULL; context->mat_f64_build_panel = NULL; context->mat_f64_clear_panel = PNL_PROC(double, sse, clear); context->mat_f64_panel_fma = NULL; context->mat_f64_pivot = NULL; context->mat_f64_store_panel = NULL; context->vec_f32_normalize_3 = f32_normalize; } void load_intrinsic_avx(sn_intrinsic *context) { context->city_hash_simplify = city_hash_simplify_sse; context->factorial_simd = factorial_simd_sse; context->index_pair = index_pair_sse; context->mat_f32_buffer_add = BUF_PROC(float, avx, add); context->mat_f32_buffer_fill = BUF_PROC(float, avx, fill); context->mat_f32_buffer_scalar_mul = BUF_PROC(float, avx, scalar_mul); context->mat_f32_buffer_sub = BUF_PROC(float, avx, sub); context->mat_f32_buffer_transpose = KER_PROC(float, avx, transpose); context->mat_f32_build_panel = BUILD_PANEL(avx, float); context->mat_f32_clear_panel = PNL_PROC(float, avx, clear); context->mat_f32_panel_fma = PNL_PROC(float, avx, fma); context->mat_f32_pivot = pivot_float; context->mat_f32_store_panel = STORE_PANEL(avx, float); context->mat_f64_buffer_add = BUF_PROC(double, avx, add); context->mat_f64_buffer_fill = BUF_PROC(double, avx, fill); context->mat_f64_buffer_scalar_mul = BUF_PROC(double, avx, scalar_mul); context->mat_f64_buffer_sub = BUF_PROC(double, avx, sub); context->mat_f64_buffer_transpose = NULL; context->mat_f64_build_panel = NULL; context->mat_f64_clear_panel = PNL_PROC(double, avx, clear); context->mat_f64_panel_fma = NULL; context->mat_f64_pivot = NULL; context->mat_f64_store_panel = NULL; context->vec_f32_normalize_3 = f32_normalize; } void load_intrinsic_512(sn_intrinsic *context) { context->city_hash_simplify = city_hash_simplify_sse; context->factorial_simd = factorial_simd_sse; context->index_pair = index_pair_sse; context->mat_f32_buffer_add = BUF_PROC(float, 512, add); context->mat_f32_buffer_fill = BUF_PROC(float, 512, fill); context->mat_f32_buffer_scalar_mul = BUF_PROC(float, 512, scalar_mul); context->mat_f32_buffer_sub = BUF_PROC(float, 512, sub); context->mat_f32_buffer_transpose = KER_PROC(float, 512, transpose); context->mat_f32_build_panel = BUILD_PANEL(512, float); context->mat_f32_clear_panel = PNL_PROC(float, 512, clear); context->mat_f32_panel_fma = PNL_PROC(float, 512, fma); context->mat_f32_pivot = pivot_float; context->mat_f32_store_panel = STORE_PANEL(512, float); context->mat_f64_buffer_add = NULL; context->mat_f64_buffer_fill = NULL; context->mat_f64_buffer_scalar_mul = NULL; context->mat_f64_buffer_sub = NULL; context->mat_f64_buffer_transpose = NULL; context->mat_f64_build_panel = NULL; context->mat_f64_clear_panel = NULL; context->mat_f64_panel_fma = NULL; context->mat_f64_pivot = NULL; context->mat_f64_store_panel = NULL; context->vec_f32_normalize_3 = f32_normalize; }