25 static inline void relu(
float *
RESTRICT x,
const size_t n)
noexcept
27 assert(n != 0 &&
"n must not be 0.");
28 assert(x !=
nullptr &&
"x must not be null.");
32#if defined(__AVX512F__)
33 const __m512 zeros512 = _mm512_setzero_ps();
34 simd_end = n - (n % 16);
36 for (
size_t i = 0; i < simd_end; i += 16)
38 __m512 xi = _mm512_loadu_ps(x + i);
39 xi = _mm512_max_ps(zeros512, xi);
40 _mm512_storeu_ps(x + i, xi);
43#elif defined(__AVX2__) || defined(__AVX__)
44 const __m256 zeros256 = _mm256_setzero_ps();
45 simd_end = n - (n % 8);
47 for (
size_t i = 0; i < simd_end; i += 8)
49 __m256 xi = _mm256_loadu_ps(x + i);
50 xi = _mm256_max_ps(zeros256, xi);
51 _mm256_storeu_ps(x + i, xi);
54#elif defined(__SSE__) || defined(_M_AMD64) || defined(_M_X64)
55 const __m128 zeros128 = _mm_setzero_ps();
56 simd_end = n - (n % 4);
58 for (
size_t i = 0; i < simd_end; i += 4)
60 __m128 xi = _mm_loadu_ps(x + i);
61 xi = _mm_max_ps(zeros128, xi);
62 _mm_storeu_ps(x + i, xi);
66 for (
size_t i = simd_end; i < n; i++)
68 x[i] =
MAX(0.0f, x[i]);
78 static inline void dRelu(
float *
RESTRICT x,
const size_t n, [[maybe_unused]]
bool activated =
false) noexcept
80 assert(n != 0 &&
"n must not be 0.");
81 assert(x !=
nullptr &&
"x must not be null.");
85#if defined(__AVX512F__)
86 __m512 ones = _mm512_set1_ps(1.0f);
87 __m512 zeros = _mm512_setzero_ps();
88 size_t simd_end4 = n - (n % 64);
90#pragma omp parallel for schedule(static) if (n > 65536 && !omp_in_parallel())
91 for (ptrdiff_t i = 0; i < (ptrdiff_t)(simd_end4); i += 64)
93 __m512 x0 = _mm512_loadu_ps(x + i);
94 __m512 x1 = _mm512_loadu_ps(x + i + 16);
95 __m512 x2 = _mm512_loadu_ps(x + i + 32);
96 __m512 x3 = _mm512_loadu_ps(x + i + 48);
98 __mmask16 m0 = _mm512_cmp_ps_mask(x0, zeros, _CMP_GT_OQ);
99 __mmask16 m1 = _mm512_cmp_ps_mask(x1, zeros, _CMP_GT_OQ);
100 __mmask16 m2 = _mm512_cmp_ps_mask(x2, zeros, _CMP_GT_OQ);
101 __mmask16 m3 = _mm512_cmp_ps_mask(x3, zeros, _CMP_GT_OQ);
103 _mm512_storeu_ps(x + i, _mm512_mask_blend_ps(m0, zeros, ones));
104 _mm512_storeu_ps(x + i + 16, _mm512_mask_blend_ps(m1, zeros, ones));
105 _mm512_storeu_ps(x + i + 32, _mm512_mask_blend_ps(m2, zeros, ones));
106 _mm512_storeu_ps(x + i + 48, _mm512_mask_blend_ps(m3, zeros, ones));
109 simd_end = n - (n % 16);
110 for (
size_t i = simd_end4; i < simd_end; i += 16)
112 __m512 x0 = _mm512_loadu_ps(x + i);
113 __mmask16 m0 = _mm512_cmp_ps_mask(x0, zeros, _CMP_GT_OQ);
114 _mm512_storeu_ps(x + i, _mm512_mask_blend_ps(m0, zeros, ones));
117#elif defined(__AVX2__) || defined(__AVX__)
118 __m256 ones = _mm256_set1_ps(1.0f);
119 __m256 zeros = _mm256_setzero_ps();
120 size_t simd_end4 = n - (n % 32);
122#pragma omp parallel for schedule(static) if (n > 65536 && !omp_in_parallel())
123 for (ptrdiff_t i = 0; i < (ptrdiff_t)(simd_end4); i += 32)
125 __m256 x0 = _mm256_loadu_ps(x + i);
126 __m256 x1 = _mm256_loadu_ps(x + i + 8);
127 __m256 x2 = _mm256_loadu_ps(x + i + 16);
128 __m256 x3 = _mm256_loadu_ps(x + i + 24);
130 x0 = _mm256_and_ps(ones, _mm256_cmp_ps(x0, zeros, _CMP_GT_OQ));
131 x1 = _mm256_and_ps(ones, _mm256_cmp_ps(x1, zeros, _CMP_GT_OQ));
132 x2 = _mm256_and_ps(ones, _mm256_cmp_ps(x2, zeros, _CMP_GT_OQ));
133 x3 = _mm256_and_ps(ones, _mm256_cmp_ps(x3, zeros, _CMP_GT_OQ));
135 _mm256_storeu_ps(x + i, x0);
136 _mm256_storeu_ps(x + i + 8, x1);
137 _mm256_storeu_ps(x + i + 16, x2);
138 _mm256_storeu_ps(x + i + 24, x3);
141 simd_end = n - (n % 8);
142 for (
size_t i = simd_end4; i < simd_end; i += 8)
144 __m256 x0 = _mm256_loadu_ps(x + i);
145 _mm256_storeu_ps(x + i, _mm256_and_ps(ones, _mm256_cmp_ps(x0, zeros, _CMP_GT_OQ)));
148#elif defined(__SSE__) || defined(_M_AMD64) || defined(_M_X64)
149 __m128 ones = _mm_set1_ps(1.0f);
150 __m128 zeros = _mm_setzero_ps();
151 size_t simd_end4 = n - (n % 16);
153#pragma omp parallel for schedule(static) if (n > 65536 && !omp_in_parallel())
154 for (ptrdiff_t i = 0; i < (ptrdiff_t)(simd_end4); i += 16)
156 __m128 x0 = _mm_loadu_ps(x + i);
157 __m128 x1 = _mm_loadu_ps(x + i + 4);
158 __m128 x2 = _mm_loadu_ps(x + i + 8);
159 __m128 x3 = _mm_loadu_ps(x + i + 12);
161 x0 = _mm_and_ps(ones, _mm_cmpgt_ps(x0, zeros));
162 x1 = _mm_and_ps(ones, _mm_cmpgt_ps(x1, zeros));
163 x2 = _mm_and_ps(ones, _mm_cmpgt_ps(x2, zeros));
164 x3 = _mm_and_ps(ones, _mm_cmpgt_ps(x3, zeros));
166 _mm_storeu_ps(x + i, x0);
167 _mm_storeu_ps(x + i + 4, x1);
168 _mm_storeu_ps(x + i + 8, x2);
169 _mm_storeu_ps(x + i + 12, x3);
172 simd_end = n - (n % 4);
173 for (
size_t i = simd_end4; i < simd_end; i += 4)
175 __m128 x0 = _mm_loadu_ps(x + i);
176 _mm_storeu_ps(x + i, _mm_and_ps(ones, _mm_cmpgt_ps(x0, zeros)));
180 for (
size_t i = simd_end; i < n; i++)
182 x[i] = (x[i] > 0.0f) ? 1.0f : 0.0f;
190 assert(n != 0 &&
"n must not be 0.");
191 assert(dst !=
nullptr &&
"dst must not be null.");
192 assert(src !=
nullptr &&
"src must not be null.");
196#if defined(__AVX512F__)
197 __m512 ones = _mm512_set1_ps(1.0f);
198 __m512 zeros = _mm512_setzero_ps();
199 size_t simd_end = n - (n % 16);
200#pragma omp parallel for schedule(static) if (n > 65536 && !omp_in_parallel())
201 for (ptrdiff_t j = 0; j < (ptrdiff_t)simd_end; j += 16)
203 __m512 s = _mm512_loadu_ps(src + j);
204 __mmask16 m = _mm512_cmp_ps_mask(s, zeros, _CMP_GT_OQ);
205 _mm512_storeu_ps(dst + j, _mm512_mask_blend_ps(m, zeros, ones));
208#elif defined(__AVX2__) || defined(__AVX__)
209 __m256 ones = _mm256_set1_ps(1.0f);
210 __m256 zeros = _mm256_setzero_ps();
211 size_t simd_end = n - (n % 8);
212#pragma omp parallel for schedule(static) if (n > 65536 && !omp_in_parallel())
213 for (ptrdiff_t j = 0; j < (ptrdiff_t)simd_end; j += 8)
215 __m256 s = _mm256_loadu_ps(src + j);
216 _mm256_storeu_ps(dst + j, _mm256_and_ps(ones, _mm256_cmp_ps(s, zeros, _CMP_GT_OQ)));
219#elif defined(__SSE__) || defined(_M_AMD64) || defined(_M_X64)
220 __m128 ones = _mm_set1_ps(1.0f);
221 __m128 zeros = _mm_setzero_ps();
222 size_t simd_end = n - (n % 4);
223#pragma omp parallel for schedule(static) if (n > 65536 && !omp_in_parallel())
224 for (ptrdiff_t j = 0; j < (ptrdiff_t)simd_end; j += 4)
226 __m128 s = _mm_loadu_ps(src + j);
227 _mm_storeu_ps(dst + j, _mm_and_ps(ones, _mm_cmpgt_ps(s, zeros)));
234 dst[i] = (src[i] > 0.0f) ? 1.0f : 0.0f;