25 assert(n != 0 &&
"n must not be 0.");
26 assert(x !=
nullptr &&
"x must not be null.");
30#if defined(__AVX512F__)
31 __m512 one = _mm512_set1_ps(1.0f);
32 __m512 neg_one = _mm512_set1_ps(-1.0f);
34 size_t simd_end = n - r;
35 for (; i < simd_end; i += 16)
37 __m512 x_512 = _mm512_loadu_ps(x + i);
38 __m512 neg_x = _mm512_mul_ps(x_512, neg_one);
39 __m512 exp_neg_x = Sleef_expf16_u10avx512f(neg_x);
40 __m512 den = _mm512_add_ps(exp_neg_x, one);
41 __m512 sig = _mm512_div_ps(one, den);
42 _mm512_storeu_ps(x + i, sig);
44#elif defined(__AVX2__)
45 __m256 one = _mm256_set1_ps(1.0f);
46 __m256 neg_one = _mm256_set1_ps(-1.0f);
48 size_t simd_end = n - r;
49 for (; i < simd_end; i += 8)
51 __m256 x_256 = _mm256_loadu_ps(x + i);
52 __m256 neg_x = _mm256_mul_ps(x_256, neg_one);
53 __m256 exp_neg_x = Sleef_expf8_u10avx2(neg_x);
54 __m256 den = _mm256_add_ps(exp_neg_x, one);
55 __m256 sig = _mm256_div_ps(one, den);
56 _mm256_storeu_ps(x + i, sig);
58#elif defined(__SSE__) || defined(_M_AMD64) || defined(_M_X64)
59 __m128 one = _mm_set1_ps(1.0f);
60 __m128 neg_one = _mm_set1_ps(-1.0f);
62 size_t simd_end = n - r;
63 for (; i < simd_end; i += 4)
65 __m128 x_128 = _mm_loadu_ps(x + i);
66 __m128 neg_x = _mm_mul_ps(x_128, neg_one);
67 __m128 exp_neg_x = Sleef_expf4_u10sse2(neg_x);
68 __m128 den = _mm_add_ps(exp_neg_x, one);
69 __m128 sig = _mm_div_ps(one, den);
70 _mm_storeu_ps(x + i, sig);
75 x[i] = 1.0f / (1.0f + std::exp(-x[i]));
84 assert(n != 0 &&
"n must not be 0.");
85 assert(x !=
nullptr &&
"x must not be null.");
89#if defined(__AVX512F__)
90 __m512 half = _mm512_set1_ps(0.5f);
91 __m512 one = _mm512_set1_ps(1.0f);
93 size_t simd_end = n - r;
94 for (; i < simd_end; i += 16)
96 __m512 x_512 = _mm512_loadu_ps(x + i);
97 __m512 den = _mm512_add_ps(
100 __m512 div = _mm512_div_ps(x_512, den);
101 __m512 sig = _mm512_fmadd_ps(div, half, half);
103 _mm512_storeu_ps(x + i, sig);
105#elif defined(__AVX2__)
106 __m256 half = _mm256_set1_ps(0.5f);
107 __m256 one = _mm256_set1_ps(1.0f);
108 __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7FFFFFFF));
110 size_t simd_end = n - r;
111 for (; i < simd_end; i += 8)
113 __m256 x_256 = _mm256_loadu_ps(x + i);
114 __m256 den = _mm256_add_ps(
115 _mm256_and_ps(x_256, mask),
117 __m256 div = _mm256_div_ps(x_256, den);
119 __m256 sig = _mm256_fmadd_ps(div, half, half);
121 __m256 sig = _mm256_add_ps(_mm256_mul_ps(div, half), half);
124 _mm256_storeu_ps(x + i, sig);
126#elif defined(__SSE__) || defined(_M_AMD64) || defined(_M_X64)
127 __m128 half = _mm_set1_ps(0.5f);
128 __m128 one = _mm_set1_ps(1.0f);
129 __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF));
131 size_t simd_end = n - r;
132 for (; i < simd_end; i += 4)
134 __m128 x_128 = _mm_loadu_ps(x + i);
135 __m128 den = _mm_add_ps(
136 _mm_and_ps(x_128, mask),
138 __m128 div = _mm_div_ps(x_128, den);
140 __m128 sig = _mm_fmadd_ps(div, half, half);
142 __m128 sig = _mm_add_ps(_mm_mul_ps(div, half), half);
145 _mm_storeu_ps(x + i, sig);
150 x[i] = 0.5f * (x[i] / (1.0f + fabsf(x[i])) + 1.0f);
159 static inline void dSigmoid(
float *
RESTRICT x,
const size_t n,
bool activated =
false) noexcept
161 assert(n != 0 &&
"n must not be 0.");
162 assert(x !=
nullptr &&
"x must not be null.");
168#if defined(__AVX512F__)
171 size_t simd_end = n - r;
172 for (; i < simd_end; i += 16)
174 __m512 x_512 = _mm512_loadu_ps(x + i);
175 __m512 d = _mm512_fnmadd_ps(x_512, x_512, x_512);
176 _mm512_storeu_ps(x + i, d);
178#elif defined(__AVX2__)
181 size_t simd_end = n - r;
182 for (; i < simd_end; i += 8)
184 __m256 x_256 = _mm256_loadu_ps(x + i);
186 __m256 d = _mm256_fnmadd_ps(x_256, x_256, x_256);
188 __m256 d = _mm256_sub_ps(x_256, _mm256_mul_ps(x_256, x_256));
190 _mm256_storeu_ps(x + i, d);
192#elif defined(__SSE__) || defined(_M_AMD64) || defined(_M_X64)
194 size_t simd_end = n - r;
195 for (; i < simd_end; i += 4)
197 __m128 x_128 = _mm_loadu_ps(x + i);
200 __m128 d = _mm_fnmadd_ps(x_128, x_128, x_128);
202 __m128 d = _mm_sub_ps(x_128, _mm_mul_ps(x_128, x_128));
204 _mm_storeu_ps(x + i, d);
210 x[i] = x[i] * (1.0f - x[i]);
221 assert(n != 0 &&
"n must not be 0.");
222 assert(dst !=
nullptr &&
"dst must not be null.");
223 assert(src !=
nullptr &&
"src must not be null.");
227#if defined(__AVX512F__)
228 __m512 one = _mm512_set1_ps(1.0f);
229 __m512 neg_one = _mm512_set1_ps(-1.0f);
230 size_t simd_end = n - (n % 16);
231#pragma omp parallel for schedule(static) if (n > 65536 && !omp_in_parallel())
232 for (ptrdiff_t j = 0; j < (ptrdiff_t)simd_end; j += 16)
234 __m512 s = _mm512_loadu_ps(src + j);
235 __m512 neg_s = _mm512_mul_ps(s, neg_one);
236 __m512 exp_neg_s = Sleef_expf16_u10avx512f(neg_s);
237 __m512 den = _mm512_add_ps(exp_neg_s, one);
238 __m512 sig = _mm512_div_ps(one, den);
239 __m512 d = _mm512_fnmadd_ps(sig, sig, sig);
240 _mm512_storeu_ps(dst + j, d);
243#elif defined(__AVX2__)
244 __m256 one = _mm256_set1_ps(1.0f);
245 __m256 neg_one = _mm256_set1_ps(-1.0f);
246 size_t simd_end = n - (n % 8);
247#pragma omp parallel for schedule(static) if (n > 65536 && !omp_in_parallel())
248 for (ptrdiff_t j = 0; j < (ptrdiff_t)simd_end; j += 8)
250 __m256 s = _mm256_loadu_ps(src + j);
251 __m256 neg_s = _mm256_mul_ps(s, neg_one);
252 __m256 exp_neg_s = Sleef_expf8_u10avx2(neg_s);
253 __m256 den = _mm256_add_ps(exp_neg_s, one);
254 __m256 sig = _mm256_div_ps(one, den);
256 __m256 d = _mm256_fnmadd_ps(sig, sig, sig);
258 __m256 d = _mm256_sub_ps(sig, _mm256_mul_ps(sig, sig));
260 _mm256_storeu_ps(dst + j, d);
263#elif defined(__SSE__) || defined(_M_AMD64) || defined(_M_X64)
264 __m128 one = _mm_set1_ps(1.0f);
265 __m128 neg_one = _mm_set1_ps(-1.0f);
266 size_t simd_end = n - (n % 4);
267#pragma omp parallel for schedule(static) if (n > 65536 && !omp_in_parallel())
268 for (ptrdiff_t j = 0; j < (ptrdiff_t)simd_end; j += 4)
270 __m128 s = _mm_loadu_ps(src + j);
271 __m128 neg_s = _mm_mul_ps(s, neg_one);
272 __m128 exp_neg_s = Sleef_expf4_u10sse2(neg_s);
273 __m128 den = _mm_add_ps(exp_neg_s, one);
274 __m128 sig = _mm_div_ps(one, den);
276 __m128 d = _mm_fnmadd_ps(sig, sig, sig);
278 __m128 d = _mm_sub_ps(sig, _mm_mul_ps(sig, sig));
280 _mm_storeu_ps(dst + j, d);
287 float sig = 1.0f / (1.0f + std::exp(-src[i]));
288 dst[i] = sig * (1.0f - sig);
299 const bool activated =
false) noexcept
301 assert(n != 0 &&
"n must not be 0.");
302 assert(x !=
nullptr &&
"x must not be null.");
309#if defined(__AVX512F__)
311 const __m512 two = _mm512_set1_ps(2.0f);
313 const size_t r = n % 16;
314 const size_t simd_end = n - r;
316 for (; i < simd_end; i += 16)
318 const __m512 x_512 = _mm512_loadu_ps(x + i);
321 const __m512 d = _mm512_mul_ps(
322 _mm512_fnmadd_ps(x_512, x_512, x_512),
325 _mm512_storeu_ps(x + i, d);
328#elif defined(__AVX2__)
330 const __m256 two = _mm256_set1_ps(2.0f);
332 const size_t r = n % 8;
333 const size_t simd_end = n - r;
335 for (; i < simd_end; i += 8)
337 const __m256 x_256 = _mm256_loadu_ps(x + i);
341 const __m256 d = _mm256_mul_ps(
342 _mm256_fnmadd_ps(x_256, x_256, x_256),
345 const __m256 d = _mm256_mul_ps(
346 _mm256_sub_ps(x_256, _mm256_mul_ps(x_256, x_256)),
350 _mm256_storeu_ps(x + i, d);
353#elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64)
355 const __m128 two = _mm_set1_ps(2.0f);
357 const size_t r = n % 4;
358 const size_t simd_end = n - r;
360 for (; i < simd_end; i += 4)
362 const __m128 x_128 = _mm_loadu_ps(x + i);
365 const __m128 d = _mm_mul_ps(
366 _mm_fnmadd_ps(x_128, x_128, x_128),
369 const __m128 d = _mm_mul_ps(
370 _mm_sub_ps(x_128, _mm_mul_ps(x_128, x_128)),
374 _mm_storeu_ps(x + i, d);
381 x[i] = 2.0f * x[i] * (1.0f - x[i]);
389 const size_t n)
noexcept
391 assert(n != 0 &&
"n must not be 0.");
392 assert(dst !=
nullptr &&
"dst must not be null.");
393 assert(src !=
nullptr &&
"src must not be null.");
397#if defined(__AVX512F__)
399 const __m512 half = _mm512_set1_ps(0.5f);
400 const __m512 one = _mm512_set1_ps(1.0f);
402 const size_t simd_end = n - (n % 16);
404#pragma omp parallel for schedule(static) if (n > 16384 && !omp_in_parallel())
405 for (ptrdiff_t j = 0; j < (ptrdiff_t)simd_end; j += 16)
407 const __m512 s = _mm512_loadu_ps(src + j);
408 const __m512 a = _mm512_add_ps(_mm512_abs_ps(s), one);
409 const __m512 d = _mm512_div_ps(half, _mm512_mul_ps(a, a));
411 _mm512_storeu_ps(dst + j, d);
416#elif defined(__AVX2__)
418 const __m256 half = _mm256_set1_ps(0.5f);
419 const __m256 one = _mm256_set1_ps(1.0f);
420 const __m256 abs_mask =
421 _mm256_castsi256_ps(_mm256_set1_epi32(0x7FFFFFFF));
423 const size_t simd_end = n - (n % 8);
425#pragma omp parallel for schedule(static) if (n > 16384 && !omp_in_parallel())
426 for (ptrdiff_t j = 0; j < (ptrdiff_t)simd_end; j += 8)
428 const __m256 s = _mm256_loadu_ps(src + j);
429 const __m256 a = _mm256_add_ps(
430 _mm256_and_ps(s, abs_mask),
433 const __m256 d = _mm256_div_ps(
435 _mm256_mul_ps(a, a));
437 _mm256_storeu_ps(dst + j, d);
442#elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64)
444 const __m128 half = _mm_set1_ps(0.5f);
445 const __m128 one = _mm_set1_ps(1.0f);
446 const __m128 abs_mask =
447 _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF));
449 const size_t simd_end = n - (n % 4);
451#pragma omp parallel for schedule(static) if (n > 16384 && !omp_in_parallel())
452 for (ptrdiff_t j = 0; j < (ptrdiff_t)simd_end; j += 4)
454 const __m128 s = _mm_loadu_ps(src + j);
455 const __m128 a = _mm_add_ps(
456 _mm_and_ps(s, abs_mask),
459 const __m128 d = _mm_div_ps(
463 _mm_storeu_ps(dst + j, d);
472 const float a = 1.0f + std::fabs(src[i]);
473 dst[i] = 0.5f / (a * a);