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