File size: 3,088 Bytes
fb6457c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | #ifndef BSH_GEMM_SIMD_VECTOR_H
#define BSH_GEMM_SIMD_VECTOR_H
#include <stddef.h>
#include <stdint.h>
#if defined(__AVX512F__)
#define SIMD_WIDTH 16
#define SIMD_BYTES 64
#include <immintrin.h>
typedef __m512 simd_f32;
typedef __m512d simd_f64;
typedef __mmask16 simd_mask;
#elif defined(__AVX2__)
#define SIMD_WIDTH 8
#define SIMD_BYTES 32
#include <immintrin.h>
typedef __m256 simd_f32;
typedef __m256d simd_f64;
#else
#define SIMD_WIDTH 1
#define SIMD_BYTES 4
typedef float simd_f32;
typedef double simd_f64;
#endif
typedef struct {
simd_f32* data;
size_t capacity;
} simd_vector_f32;
simd_vector_f32 simd_vector_create_f32(size_t capacity);
void simd_vector_free(simd_vector_f32 vec);
#ifdef __AVX512F__
static inline simd_f32 simd_zero_f32(void) {
return _mm512_setzero_ps();
}
static inline simd_f32 simd_broadcast_f32(float val) {
return _mm512_set1_ps(val);
}
static inline simd_f32 simd_load_f32(const float* ptr) {
return _mm512_loadu_ps(ptr);
}
static inline void simd_store_f32(float* ptr, simd_f32 v) {
_mm512_storeu_ps(ptr, v);
}
static inline simd_f32 simd_add_f32(simd_f32 a, simd_f32 b) {
return _mm512_add_ps(a, b);
}
static inline simd_f32 simd_sub_f32(simd_f32 a, simd_f32 b) {
return _mm512_sub_ps(a, b);
}
static inline simd_f32 simd_mul_f32(simd_f32 a, simd_f32 b) {
return _mm512_mul_ps(a, b);
}
static inline simd_f32 simd_fma_f32(simd_f32 a, simd_f32 b, simd_f32 c) {
return _mm512_fmadd_ps(a, b, c);
}
static inline simd_f32 simd_reduce_add_f32(simd_f32 v) {
return _mm512_reduce_add_ps(v);
}
#elif defined(__AVX2__)
static inline simd_f32 simd_zero_f32(void) {
return _mm256_setzero_ps();
}
static inline simd_f32 simd_broadcast_f32(float val) {
return _mm256_set1_ps(val);
}
static inline simd_f32 simd_load_f32(const float* ptr) {
return _mm256_loadu_ps(ptr);
}
static inline void simd_store_f32(float* ptr, simd_f32 v) {
_mm256_storeu_ps(ptr, v);
}
static inline simd_f32 simd_add_f32(simd_f32 a, simd_f32 b) {
return _mm256_add_ps(a, b);
}
static inline simd_f32 simd_sub_f32(simd_f32 a, simd_f32 b) {
return _mm256_sub_ps(a, b);
}
static inline simd_f32 simd_mul_f32(simd_f32 a, simd_f32 b) {
return _mm256_mul_ps(a, b);
}
static inline simd_f32 simd_fma_f32(simd_f32 a, simd_f32 b, simd_f32 c) {
return _mm256_fmadd_ps(a, b, c);
}
#else
static inline simd_f32 simd_zero_f32(void) {
return 0.0f;
}
static inline simd_f32 simd_broadcast_f32(float val) {
return val;
}
static inline simd_f32 simd_load_f32(const float* ptr) {
return *ptr;
}
static inline void simd_store_f32(float* ptr, simd_f32 v) {
*ptr = v;
}
static inline simd_f32 simd_add_f32(simd_f32 a, simd_f32 b) {
return a + b;
}
static inline simd_f32 simd_sub_f32(simd_f32 a, simd_f32 b) {
return a - b;
}
static inline simd_f32 simd_mul_f32(simd_f32 a, simd_f32 b) {
return a * b;
}
static inline simd_f32 simd_fma_f32(simd_f32 a, simd_f32 b, simd_f32 c) {
return a * b + c;
}
#endif
#endif
|