From 29b9bf38747d28be5fa9fdf3e73b77646156aa83 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 4 Aug 2026 10:48:08 +0000 Subject: [PATCH] Rename NeuralAddVectorMultipliedByValue to SynetAddVectorMultipliedByValue. Move architecture implementations into dedicated SynetMath.cpp files, relocate the auto-test to TestSynetMath.cpp, update VS2022 projects, and refresh release 7.2.165 notes in docs/2026.html. Co-authored-by: Ihar Yermalayeu --- docs/2026.html | 13 ++- prj/vs2022/Avx2.vcxproj | 1 + prj/vs2022/Avx2.vcxproj.filters | 6 ++ prj/vs2022/Avx512bw.vcxproj | 1 + prj/vs2022/Avx512bw.vcxproj.filters | 6 ++ prj/vs2022/Base.vcxproj | 1 + prj/vs2022/Base.vcxproj.filters | 6 ++ prj/vs2022/Neon.vcxproj | 1 + prj/vs2022/Neon.vcxproj.filters | 6 ++ prj/vs2022/Sse41.vcxproj | 1 + prj/vs2022/Sse41.vcxproj.filters | 6 ++ prj/vs2022/Sve2.vcxproj | 1 + prj/vs2022/Sve2.vcxproj.filters | 3 + prj/vs2022/Test.vcxproj | 1 + prj/vs2022/Test.vcxproj.filters | 6 ++ src/Simd/SimdAvx2.h | 4 +- src/Simd/SimdAvx2Neural.cpp | 12 --- src/Simd/SimdAvx2SynetMath.cpp | 46 ++++++++++ src/Simd/SimdAvx512bw.h | 4 +- src/Simd/SimdAvx512bwNeural.cpp | 12 --- src/Simd/SimdAvx512bwSynetMath.cpp | 46 ++++++++++ src/Simd/SimdBase.h | 4 +- src/Simd/SimdBaseNeural.cpp | 5 -- src/Simd/SimdBaseSynetMath.cpp | 51 ++++++++++++ src/Simd/SimdLib.cpp | 22 +++-- src/Simd/SimdLib.h | 42 +++++----- src/Simd/SimdNeon.h | 4 +- src/Simd/SimdNeonNeural.cpp | 12 --- src/Simd/SimdNeonSynetMath.cpp | 46 ++++++++++ src/Simd/SimdNeural.hpp | 8 +- src/Simd/SimdSse41.h | 4 +- src/Simd/SimdSse41Neural.cpp | 12 --- src/Simd/SimdSse41SynetMath.cpp | 46 ++++++++++ src/Simd/SimdSve2.h | 4 +- src/Simd/SimdSve2Neural.cpp | 24 ------ src/Simd/SimdSve2SynetMath.cpp | 58 +++++++++++++ src/Test/Test.cpp | 2 +- src/Test/TestDescrInt.cpp | 4 +- src/Test/TestNeural.cpp | 93 --------------------- src/Test/TestSynetMath.cpp | 125 ++++++++++++++++++++++++++++ 40 files changed, 528 insertions(+), 221 deletions(-) create mode 100644 src/Simd/SimdAvx2SynetMath.cpp create mode 100644 src/Simd/SimdAvx512bwSynetMath.cpp create mode 100644 src/Simd/SimdBaseSynetMath.cpp create mode 100644 src/Simd/SimdNeonSynetMath.cpp create mode 100644 src/Simd/SimdSse41SynetMath.cpp create mode 100644 src/Simd/SimdSve2SynetMath.cpp create mode 100644 src/Test/TestSynetMath.cpp diff --git a/docs/2026.html b/docs/2026.html index bd37535686..64dbddbed4 100644 --- a/docs/2026.html +++ b/docs/2026.html @@ -54,11 +54,22 @@
Renaming
+
Improving
+
Removing
+

Test framework

+
Improving
+ Home
@@ -690,7 +701,7 @@
Improving
  • Description of function SimdNeuralDerivativeRelu.
  • Description of function SimdNeuralPow.
  • Description of function SimdNeuralProductSum.
  • -
  • Description of function SimdNeuralAddVectorMultipliedByValue.
  • +
  • Description of function SimdSynetAddVectorMultipliedByValue.
  • Description of function SimdNeuralAddVector.
  • Description of function SimdNeuralAddValue.
  • Description of function SimdNeuralUpdateWeights.
  • diff --git a/prj/vs2022/Avx2.vcxproj b/prj/vs2022/Avx2.vcxproj index 3be0c31bd4..f609877027 100644 --- a/prj/vs2022/Avx2.vcxproj +++ b/prj/vs2022/Avx2.vcxproj @@ -94,6 +94,7 @@ + diff --git a/prj/vs2022/Avx2.vcxproj.filters b/prj/vs2022/Avx2.vcxproj.filters index d336ee93d1..7300a1cb4b 100644 --- a/prj/vs2022/Avx2.vcxproj.filters +++ b/prj/vs2022/Avx2.vcxproj.filters @@ -385,6 +385,9 @@ Avx2\Synet\Other + + Avx2\Synet\Math + Avx2\Synet\Other @@ -881,6 +884,9 @@ {060c92c0-25b8-4741-92fa-59e8b81dde16} + + {b9e2d3c4-5f60-789a-bcde-f01234567890} + {4231543b-7eb7-4d6e-9634-d94c5681cc2d} diff --git a/prj/vs2022/Avx512bw.vcxproj b/prj/vs2022/Avx512bw.vcxproj index 5a4c12ad23..ed632617aa 100644 --- a/prj/vs2022/Avx512bw.vcxproj +++ b/prj/vs2022/Avx512bw.vcxproj @@ -94,6 +94,7 @@ + diff --git a/prj/vs2022/Avx512bw.vcxproj.filters b/prj/vs2022/Avx512bw.vcxproj.filters index 11c6965fd7..c75923d8ca 100644 --- a/prj/vs2022/Avx512bw.vcxproj.filters +++ b/prj/vs2022/Avx512bw.vcxproj.filters @@ -172,6 +172,9 @@ Avx512bw\Synet\Other + + Avx512bw\Synet\Math + Avx512bw\Synet\Other @@ -549,6 +552,9 @@ {96af6533-5366-481d-b0c1-98688f359626} + + {c0f3e4d5-6071-89ab-cdef-012345678901} + {e83490b5-ddf0-4ee4-98b0-d2c6a065b872} diff --git a/prj/vs2022/Base.vcxproj b/prj/vs2022/Base.vcxproj index 0064ee387a..4047818a9d 100644 --- a/prj/vs2022/Base.vcxproj +++ b/prj/vs2022/Base.vcxproj @@ -218,6 +218,7 @@ + diff --git a/prj/vs2022/Base.vcxproj.filters b/prj/vs2022/Base.vcxproj.filters index 7852fc6035..2a354b3807 100644 --- a/prj/vs2022/Base.vcxproj.filters +++ b/prj/vs2022/Base.vcxproj.filters @@ -379,6 +379,9 @@ Base\Synet\Other + + Base\Synet\Math + Base\Synet\Other @@ -866,6 +869,9 @@ {8e40dd5b-5304-43d8-93e9-fbf902e8b4e0} + + {137c37ff-5db2-4273-b166-8e293df23931} + {604d9236-47f2-4636-98c7-3e0e5a2629ca} diff --git a/prj/vs2022/Neon.vcxproj b/prj/vs2022/Neon.vcxproj index 6be1cfd2d5..7799abe61e 100644 --- a/prj/vs2022/Neon.vcxproj +++ b/prj/vs2022/Neon.vcxproj @@ -104,6 +104,7 @@ + diff --git a/prj/vs2022/Neon.vcxproj.filters b/prj/vs2022/Neon.vcxproj.filters index cf83775694..3875b11414 100644 --- a/prj/vs2022/Neon.vcxproj.filters +++ b/prj/vs2022/Neon.vcxproj.filters @@ -346,6 +346,9 @@ Neon\Synet\Other + + Neon\Synet\Math + Neon\Synet\Other @@ -477,6 +480,9 @@ {70d03600-18de-48a5-bc25-212969871a71} + + {d1a4f5e6-7182-9abc-def0-123456789012} + diff --git a/prj/vs2022/Sse41.vcxproj b/prj/vs2022/Sse41.vcxproj index d3ae837cc4..e559746dcb 100644 --- a/prj/vs2022/Sse41.vcxproj +++ b/prj/vs2022/Sse41.vcxproj @@ -98,6 +98,7 @@ + diff --git a/prj/vs2022/Sse41.vcxproj.filters b/prj/vs2022/Sse41.vcxproj.filters index 7830de7e52..b306cb0c14 100644 --- a/prj/vs2022/Sse41.vcxproj.filters +++ b/prj/vs2022/Sse41.vcxproj.filters @@ -469,6 +469,9 @@ Sse41\Synet\Other + + Sse41\Synet\Math + Sse41\Synet\Other @@ -582,6 +585,9 @@ {7521bba2-dca9-4177-8ab8-03223a7b4c08} + + {a8f1c2d3-4e5f-6789-abcd-ef0123456789} + {1e361225-f424-4df8-8665-aa6ec1d864ee} diff --git a/prj/vs2022/Sve2.vcxproj b/prj/vs2022/Sve2.vcxproj index 28cdc94253..f1cbc63565 100644 --- a/prj/vs2022/Sve2.vcxproj +++ b/prj/vs2022/Sve2.vcxproj @@ -103,6 +103,7 @@ + diff --git a/prj/vs2022/Sve2.vcxproj.filters b/prj/vs2022/Sve2.vcxproj.filters index cf9fd2289b..7946ade9ca 100644 --- a/prj/vs2022/Sve2.vcxproj.filters +++ b/prj/vs2022/Sve2.vcxproj.filters @@ -497,6 +497,9 @@ Sve2\Synet\Math + + Sve2\Synet\Math + Sve2\Synet\Math diff --git a/prj/vs2022/Test.vcxproj b/prj/vs2022/Test.vcxproj index 0e80e48523..abc4ac77bd 100644 --- a/prj/vs2022/Test.vcxproj +++ b/prj/vs2022/Test.vcxproj @@ -114,6 +114,7 @@ + diff --git a/prj/vs2022/Test.vcxproj.filters b/prj/vs2022/Test.vcxproj.filters index b7d8cb5664..b3ae3673d7 100644 --- a/prj/vs2022/Test.vcxproj.filters +++ b/prj/vs2022/Test.vcxproj.filters @@ -262,6 +262,9 @@ Test\Synet\Other + + Test\Synet\Math + Test\Synet\Other @@ -413,6 +416,9 @@ {11a212bb-9bd8-47bd-ad41-ccdde5c25c10} + + {8cc7b54c-1fd3-4516-83f4-95342005063d} + {5027f37e-3061-4ab5-aa0a-79e863f0fed0} diff --git a/src/Simd/SimdAvx2.h b/src/Simd/SimdAvx2.h index 5593367c15..9f50675ab3 100644 --- a/src/Simd/SimdAvx2.h +++ b/src/Simd/SimdAvx2.h @@ -338,8 +338,6 @@ namespace Simd void NeuralProductSum(const float * a, const float * b, size_t size, float * sum); - void NeuralAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); - void NeuralDerivativeRelu(const float* src, size_t size, const float* slope, float* dst); void NeuralDerivativeTanh(const float* src, size_t size, const float* slope, float* dst); @@ -499,6 +497,8 @@ namespace Simd void SynetAddBias(const float* bias, size_t channels, size_t spatial, float* dst, SimdTensorFormatType format); + void SynetAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); + void SynetChannelSum16b(const uint16_t* src, size_t channels, size_t spatial, SimdTensorFormatType format, float* sum); void SynetConvert32fTo8u(const float* src, size_t batch, size_t channels, size_t height, size_t width, SimdTensorFormatType format, diff --git a/src/Simd/SimdAvx2Neural.cpp b/src/Simd/SimdAvx2Neural.cpp index 9fdcce5565..75519f635e 100644 --- a/src/Simd/SimdAvx2Neural.cpp +++ b/src/Simd/SimdAvx2Neural.cpp @@ -270,18 +270,6 @@ namespace Simd //------------------------------------------------------------------------------------------------- - void NeuralAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst) - { - size_t aligned = AlignLo(size, QF); - size_t partial = AlignLo(size, F); - if (Aligned(src) && Aligned(dst)) - AddMultiplied(src, aligned, partial, size, *value, dst); - else - AddMultiplied(src, aligned, partial, size, *value, dst); - } - - //------------------------------------------------------------------------------------------------- - template SIMD_INLINE void NeuralDerivativeSigmoid(const float* src, size_t size, const float* slope, float* dst) { size_t alignedSize = Simd::AlignLo(size, F); diff --git a/src/Simd/SimdAvx2SynetMath.cpp b/src/Simd/SimdAvx2SynetMath.cpp new file mode 100644 index 0000000000..ffe8e56d87 --- /dev/null +++ b/src/Simd/SimdAvx2SynetMath.cpp @@ -0,0 +1,46 @@ +/* +* Simd Library (http://ermig1979.github.io/Simd). +* +* Copyright (c) 2011-2026 Yermalayeu Ihar. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ +#include "Simd/SimdMemory.h" +#include "Simd/SimdStore.h" +#include "Simd/SimdNeural.h" + +namespace Simd +{ +#ifdef SIMD_AVX2_ENABLE +#if defined(SIMD_SYNET_ENABLE) + namespace Avx2 + { + void SynetAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst) + { + size_t aligned = AlignLo(size, QF); + size_t partial = AlignLo(size, F); + if (Aligned(src) && Aligned(dst)) + AddMultiplied(src, aligned, partial, size, *value, dst); + else + AddMultiplied(src, aligned, partial, size, *value, dst); + } + } +#endif +#endif +} diff --git a/src/Simd/SimdAvx512bw.h b/src/Simd/SimdAvx512bw.h index b1d20a6ee4..1d1b18aaa0 100644 --- a/src/Simd/SimdAvx512bw.h +++ b/src/Simd/SimdAvx512bw.h @@ -352,8 +352,6 @@ namespace Simd void NeuralAddVector(const float* src, size_t size, float* dst); - void NeuralAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst); - void NeuralConvert(const uint8_t * src, size_t srcStride, size_t width, size_t height, float * dst, size_t dstStride, int inversion); void NeuralConvolutionForward(const float* src, size_t srcWidth, size_t srcHeight, size_t srcDepth, const float* weight, @@ -493,6 +491,8 @@ namespace Simd void SynetAddBias(const float* bias, size_t channels, size_t spatial, float* dst, SimdTensorFormatType format); + void SynetAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst); + void SynetChannelSum16b(const uint16_t* src, size_t channels, size_t spatial, SimdTensorFormatType format, float* sum); void SynetConvert32fTo8u(const float* src, size_t batch, size_t channels, size_t height, size_t width, SimdTensorFormatType format, diff --git a/src/Simd/SimdAvx512bwNeural.cpp b/src/Simd/SimdAvx512bwNeural.cpp index d3210f7da1..3d992734b3 100644 --- a/src/Simd/SimdAvx512bwNeural.cpp +++ b/src/Simd/SimdAvx512bwNeural.cpp @@ -109,18 +109,6 @@ namespace Simd //----------------------------------------------------------------------------------------- - void NeuralAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst) - { - size_t aligned = AlignLo(size, QF); - size_t partial = AlignLo(size, F); - if (Aligned(src) && Aligned(dst)) - AddMultiplied(src, aligned, partial, size, *value, dst); - else - AddMultiplied(src, aligned, partial, size, *value, dst); - } - - //----------------------------------------------------------------------------------------- - template SIMD_INLINE void AdaptiveGradientUpdate(const float* delta, const __m512& norm, const __m512& alpha, const __m512& epsilon, float* gradient, float* weight, __mmask16 m) { __m512 _delta = Load(delta, m); diff --git a/src/Simd/SimdAvx512bwSynetMath.cpp b/src/Simd/SimdAvx512bwSynetMath.cpp new file mode 100644 index 0000000000..51dc0cdba0 --- /dev/null +++ b/src/Simd/SimdAvx512bwSynetMath.cpp @@ -0,0 +1,46 @@ +/* +* Simd Library (http://ermig1979.github.io/Simd). +* +* Copyright (c) 2011-2026 Yermalayeu Ihar. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ +#include "Simd/SimdMemory.h" +#include "Simd/SimdStore.h" +#include "Simd/SimdNeural.h" + +namespace Simd +{ +#ifdef SIMD_AVX512BW_ENABLE +#if defined(SIMD_SYNET_ENABLE) + namespace Avx512bw + { + void SynetAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst) + { + size_t aligned = AlignLo(size, QF); + size_t partial = AlignLo(size, F); + if (Aligned(src) && Aligned(dst)) + AddMultiplied(src, aligned, partial, size, *value, dst); + else + AddMultiplied(src, aligned, partial, size, *value, dst); + } + } +#endif +#endif +} diff --git a/src/Simd/SimdBase.h b/src/Simd/SimdBase.h index e7977d0f05..79008656f3 100644 --- a/src/Simd/SimdBase.h +++ b/src/Simd/SimdBase.h @@ -382,8 +382,6 @@ namespace Simd void NeuralProductSum(const float * a, const float * b, size_t size, float * sum); - void NeuralAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); - void NeuralAddVector(const float * src, size_t size, float * dst); void NeuralAddValue(const float * value, float * dst, size_t size); @@ -555,6 +553,8 @@ namespace Simd void SynetAddBias(const float * bias, size_t channels, size_t spatial, float * dst, SimdTensorFormatType format); + void SynetAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); + void SynetAdd8i(const uint8_t* aData, const float* aScale, const float* aShift, const uint8_t* bData, const float* bScale, const float* bShift, uint8_t* cData, const float* cScale, const float* cShift, size_t batch, size_t channels, size_t spatial, SimdTensorFormatType format, SimdSynetCompatibilityType compatibility); diff --git a/src/Simd/SimdBaseNeural.cpp b/src/Simd/SimdBaseNeural.cpp index 485af5012f..6a62ad4245 100644 --- a/src/Simd/SimdBaseNeural.cpp +++ b/src/Simd/SimdBaseNeural.cpp @@ -83,11 +83,6 @@ namespace Simd dst[i] += src[i] * value; } - void NeuralAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst) - { - AddMultiplied(src, Simd::AlignLo(size, 4), size, *value, dst); - } - void NeuralAddVector(const float * src, size_t size, float * dst) { size_t aligned = Simd::AlignLo(size, 4); diff --git a/src/Simd/SimdBaseSynetMath.cpp b/src/Simd/SimdBaseSynetMath.cpp new file mode 100644 index 0000000000..db440a95e3 --- /dev/null +++ b/src/Simd/SimdBaseSynetMath.cpp @@ -0,0 +1,51 @@ +/* +* Simd Library (http://ermig1979.github.io/Simd). +* +* Copyright (c) 2011-2026 Yermalayeu Ihar. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ +#include "Simd/SimdMemory.h" + +namespace Simd +{ +#if defined(SIMD_SYNET_ENABLE) + namespace Base + { + SIMD_INLINE void AddMultiplied(const float * src, size_t aligned, size_t full, float value, float * dst) + { + size_t i = 0; + for (; i < aligned; i += 4) + { + dst[i + 0] += src[i + 0] * value; + dst[i + 1] += src[i + 1] * value; + dst[i + 2] += src[i + 2] * value; + dst[i + 3] += src[i + 3] * value; + } + for (; i < full; ++i) + dst[i] += src[i] * value; + } + + void SynetAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst) + { + AddMultiplied(src, Simd::AlignLo(size, 4), size, *value, dst); + } + } +#endif +} diff --git a/src/Simd/SimdLib.cpp b/src/Simd/SimdLib.cpp index e1e9972e10..38a59821b6 100644 --- a/src/Simd/SimdLib.cpp +++ b/src/Simd/SimdLib.cpp @@ -4150,15 +4150,6 @@ SIMD_API void SimdNeuralAddVector(const float * src, size_t size, float * dst) simdNeuralAddVector(src, size, dst); } -SIMD_API void SimdNeuralAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst) -{ - SIMD_EMPTY(); - typedef void(*SimdNeuralAddVectorMultipliedByValuePtr) (const float * src, size_t size, const float * value, float * dst); - const static SimdNeuralAddVectorMultipliedByValuePtr simdNeuralAddVectorMultipliedByValue = SIMD_FUNC5(NeuralAddVectorMultipliedByValue, SIMD_AVX512BW_FUNC, SIMD_AVX2_FUNC, SIMD_SSE41_FUNC, SIMD_SVE2_FUNC, SIMD_NEON_FUNC); - - simdNeuralAddVectorMultipliedByValue(src, size, value, dst); -} - SIMD_API void SimdNeuralDerivativeSigmoid(const float * src, size_t size, const float * slope, float * dst) { SIMD_EMPTY(); @@ -6134,6 +6125,19 @@ SIMD_API void SimdSynetAddBias(const float * bias, size_t channels, size_t spati #endif } +SIMD_API void SimdSynetAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst) +{ + SIMD_EMPTY(); +#if defined(SIMD_SYNET_ENABLE) + typedef void(*SimdSynetAddVectorMultipliedByValuePtr) (const float * src, size_t size, const float * value, float * dst); + const static SimdSynetAddVectorMultipliedByValuePtr simdSynetAddVectorMultipliedByValue = SIMD_FUNC5(SynetAddVectorMultipliedByValue, SIMD_AVX512BW_FUNC, SIMD_AVX2_FUNC, SIMD_SSE41_FUNC, SIMD_SVE2_FUNC, SIMD_NEON_FUNC); + + simdSynetAddVectorMultipliedByValue(src, size, value, dst); +#else + assert(0); +#endif +} + SIMD_API void SimdSynetAdd8i(const uint8_t* aData, const float* aScale, const float* aShift, const uint8_t* bData, const float* bScale, const float* bShift, uint8_t* cData, const float* cScale, const float* cShift, size_t batch, size_t channels, size_t spatial, SimdTensorFormatType format, SimdSynetCompatibilityType compatibility) { diff --git a/src/Simd/SimdLib.h b/src/Simd/SimdLib.h index 2ae7e1ed46..43f9355ff8 100644 --- a/src/Simd/SimdLib.h +++ b/src/Simd/SimdLib.h @@ -5480,28 +5480,6 @@ extern "C" */ SIMD_DEPRECATED SIMD_API void SimdNeuralProductSum(const float * a, const float * b, size_t size, float * sum); - /*! @ingroup neural - - \fn void SimdNeuralAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); - - \short Adds a source vector multiplied by a scalar to a destination vector. - - \deprecated This function will be removed in the nearest future. - - For every element: - \verbatim - dst[i] += src[i]*value[0]; - \endverbatim - - \note This function is used in Simd::Neural. - - \param [in] src - a pointer to the input 32-bit float array. - \param [in] size - a size of arrays. - \param [in] value - a pointer to the scalar 32-bit float value. - \param [in, out] dst - a pointer to cumulative 32-bit float array. - */ - SIMD_DEPRECATED SIMD_API void SimdNeuralAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); - /*! @ingroup neural \fn void SimdNeuralAddVector(const float * src, size_t size, float * dst); @@ -7612,6 +7590,26 @@ extern "C" */ SIMD_API void SimdSynetAddBias(const float * bias, size_t channels, size_t spatial, float * dst, SimdTensorFormatType format); + /*! @ingroup synet_other + + \fn void SimdSynetAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); + + \short Adds a source vector multiplied by a scalar to a destination vector. + + For every element: + \verbatim + dst[i] += src[i]*value[0]; + \endverbatim + + \note This function is used in Synet Framework. + + \param [in] src - a pointer to the input 32-bit float array. + \param [in] size - a size of arrays. + \param [in] value - a pointer to the scalar 32-bit float value. + \param [in, out] dst - a pointer to cumulative 32-bit float array. + */ + SIMD_API void SimdSynetAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); + /*! @ingroup synet_add \fn void SimdSynetAdd8i(const uint8_t * aData, const float * aScale, const float* aShift, const uint8_t* bData, const float* bScale, const float* bShift, uint8_t* cData, const float* cScale, const float* cShift, size_t batch, size_t channels, size_t spatial, SimdTensorFormatType format, SimdSynetCompatibilityType compatibility); diff --git a/src/Simd/SimdNeon.h b/src/Simd/SimdNeon.h index 6391900dbf..fe952b3f0d 100644 --- a/src/Simd/SimdNeon.h +++ b/src/Simd/SimdNeon.h @@ -343,8 +343,6 @@ namespace Simd void NeuralProductSum(const float * a, const float * b, size_t size, float * sum); - void NeuralAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); - void NeuralAddVector(const float * src, size_t size, float * dst); void NeuralAddValue(const float * value, float * dst, size_t size); @@ -506,6 +504,8 @@ namespace Simd void SynetAddBias(const float * bias, size_t channels, size_t spatial, float * dst, SimdTensorFormatType format); + void SynetAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst); + void SynetChannelSum16b(const uint16_t* src, size_t channels, size_t spatial, SimdTensorFormatType format, float* sum); void SynetConvert32fTo8u(const float* src, size_t batch, size_t channels, size_t height, size_t width, SimdTensorFormatType format, const float* scale, const float* shift, uint8_t* dst, SimdSynetCompatibilityType compatibility); diff --git a/src/Simd/SimdNeonNeural.cpp b/src/Simd/SimdNeonNeural.cpp index c5ca9c1427..5241e422d4 100644 --- a/src/Simd/SimdNeonNeural.cpp +++ b/src/Simd/SimdNeonNeural.cpp @@ -143,18 +143,6 @@ namespace Simd //------------------------------------------------------------------------------------------------- - void NeuralAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst) - { - size_t aligned = AlignLo(size, QF); - size_t partial = AlignLo(size, F); - if (Aligned(src) && Aligned(dst)) - AddMultiplied(src, aligned, partial, size, *value, dst); - else - AddMultiplied(src, aligned, partial, size, *value, dst); - } - - //------------------------------------------------------------------------------------------------- - template SIMD_INLINE void AddVector(const float * src, float * dst) { Store(dst, vaddq_f32(Load(dst), Load(src))); diff --git a/src/Simd/SimdNeonSynetMath.cpp b/src/Simd/SimdNeonSynetMath.cpp new file mode 100644 index 0000000000..f2b0cc54e6 --- /dev/null +++ b/src/Simd/SimdNeonSynetMath.cpp @@ -0,0 +1,46 @@ +/* +* Simd Library (http://ermig1979.github.io/Simd). +* +* Copyright (c) 2011-2026 Yermalayeu Ihar. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ +#include "Simd/SimdMemory.h" +#include "Simd/SimdStore.h" +#include "Simd/SimdNeural.h" + +namespace Simd +{ +#ifdef SIMD_NEON_ENABLE +#if defined(SIMD_SYNET_ENABLE) + namespace Neon + { + void SynetAddVectorMultipliedByValue(const float * src, size_t size, const float * value, float * dst) + { + size_t aligned = AlignLo(size, QF); + size_t partial = AlignLo(size, F); + if (Aligned(src) && Aligned(dst)) + AddMultiplied(src, aligned, partial, size, *value, dst); + else + AddMultiplied(src, aligned, partial, size, *value, dst); + } + } +#endif +#endif +} diff --git a/src/Simd/SimdNeural.hpp b/src/Simd/SimdNeural.hpp index eec7052b62..afa3c98683 100644 --- a/src/Simd/SimdNeural.hpp +++ b/src/Simd/SimdNeural.hpp @@ -719,7 +719,7 @@ namespace Simd if (_functionForward) _functionForward(psrc, _padded.width, _dst.width, _dst.height, pweight, psum, _dst.width); else if (_core.width == 1 && _core.height == 1) - ::SimdNeuralAddVectorMultipliedByValue(psrc, _dst.width*_dst.height, pweight, psum); + ::SimdSynetAddVectorMultipliedByValue(psrc, _dst.width*_dst.height, pweight, psum); else { for (ptrdiff_t y = 0; y < _dst.height; y++) @@ -779,7 +779,7 @@ namespace Simd if (_functionBackward) _functionBackward(psrc, _dst.width, _dst.width, _dst.height, pweight, pdst, _padded.width); else if (_core.width == 1 && _core.height == 1) - ::SimdNeuralAddVectorMultipliedByValue(psrc, _dst.width*_dst.height, pweight, pdst); + ::SimdSynetAddVectorMultipliedByValue(psrc, _dst.width*_dst.height, pweight, pdst); else { for (ptrdiff_t y = 0; y < _dst.height; y++) @@ -1235,7 +1235,7 @@ namespace Simd assert(!_reordered); Detail::SetZero(sum); for (size_t i = 0; i < src.size(); i++) - ::SimdNeuralAddVectorMultipliedByValue(&_weight[i*_dst.width], sum.size(), &src[i], sum.data()); + ::SimdSynetAddVectorMultipliedByValue(&_weight[i*_dst.width], sum.size(), &src[i], sum.data()); if (_bias.size()) ::SimdNeuralAddVector(_bias.data(), sum.size(), sum.data()); } @@ -1256,7 +1256,7 @@ namespace Simd _prev->_function.derivative(&prevDst[0], prevDst.size(), &prevDelta[0]); for (ptrdiff_t i = 0; i < _src.width; i++) - ::SimdNeuralAddVectorMultipliedByValue(&currDelta[0], _dst.width, &prevDst[i], &dWeight[i*_dst.width]); + ::SimdSynetAddVectorMultipliedByValue(&currDelta[0], _dst.width, &prevDst[i], &dWeight[i*_dst.width]); if (_bias.size()) ::SimdNeuralAddVector(currDelta.data(), _dst.width, dBias.data()); diff --git a/src/Simd/SimdSse41.h b/src/Simd/SimdSse41.h index 2eb937314a..e0a9da30b7 100644 --- a/src/Simd/SimdSse41.h +++ b/src/Simd/SimdSse41.h @@ -333,8 +333,6 @@ namespace Simd void NeuralAdaptiveGradientUpdate(const float* delta, size_t size, size_t batch, const float* alpha, const float* epsilon, float* gradient, float* weight); - void NeuralAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst); - void NeuralAddVector(const float* src, size_t size, float* dst); void NeuralAddValue(const float* value, float* dst, size_t size); @@ -478,6 +476,8 @@ namespace Simd void SynetAddBias(const float* bias, size_t channels, size_t spatial, float* dst, SimdTensorFormatType format); + void SynetAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst); + void SynetChannelSum16b(const uint16_t* src, size_t channels, size_t spatial, SimdTensorFormatType format, float* sum); void SynetDequantizeLinear(const uint8_t* src, size_t size, int32_t bias, const float* norm, float* dst); diff --git a/src/Simd/SimdSse41Neural.cpp b/src/Simd/SimdSse41Neural.cpp index 3e9984038c..ef37b23db6 100644 --- a/src/Simd/SimdSse41Neural.cpp +++ b/src/Simd/SimdSse41Neural.cpp @@ -89,18 +89,6 @@ namespace Simd //------------------------------------------------------------------------------------------------- - void NeuralAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst) - { - size_t aligned = AlignLo(size, QF); - size_t partial = AlignLo(size, F); - if (Aligned(src) && Aligned(dst)) - AddMultiplied(src, aligned, partial, size, *value, dst); - else - AddMultiplied(src, aligned, partial, size, *value, dst); - } - - //------------------------------------------------------------------------------------------------- - template SIMD_INLINE void AddVector(const float* src, float* dst) { Store(dst, _mm_add_ps(Load(dst), Load(src))); diff --git a/src/Simd/SimdSse41SynetMath.cpp b/src/Simd/SimdSse41SynetMath.cpp new file mode 100644 index 0000000000..84dc0b116b --- /dev/null +++ b/src/Simd/SimdSse41SynetMath.cpp @@ -0,0 +1,46 @@ +/* +* Simd Library (http://ermig1979.github.io/Simd). +* +* Copyright (c) 2011-2026 Yermalayeu Ihar. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ +#include "Simd/SimdMemory.h" +#include "Simd/SimdStore.h" +#include "Simd/SimdNeural.h" + +namespace Simd +{ +#ifdef SIMD_SSE41_ENABLE +#if defined(SIMD_SYNET_ENABLE) + namespace Sse41 + { + void SynetAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst) + { + size_t aligned = AlignLo(size, QF); + size_t partial = AlignLo(size, F); + if (Aligned(src) && Aligned(dst)) + AddMultiplied(src, aligned, partial, size, *value, dst); + else + AddMultiplied(src, aligned, partial, size, *value, dst); + } + } +#endif +#endif +} diff --git a/src/Simd/SimdSve2.h b/src/Simd/SimdSve2.h index 7e898b51d1..b40ea4ddb5 100644 --- a/src/Simd/SimdSve2.h +++ b/src/Simd/SimdSve2.h @@ -145,8 +145,6 @@ namespace Simd void NeuralProductSum(const float* a, const float* b, size_t size, float* sum); - void NeuralAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst); - void NeuralAddVector(const float* src, size_t size, float* dst); void NeuralAddValue(const float* value, float* dst, size_t size); @@ -591,6 +589,8 @@ namespace Simd void SynetAddBias(const float* bias, size_t channels, size_t spatial, float* dst, SimdTensorFormatType format); + void SynetAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst); + void SynetChannelSum16b(const uint16_t* src, size_t channels, size_t spatial, SimdTensorFormatType format, float* sum); void SynetConvert32fTo8u(const float* src, size_t batch, size_t channels, size_t height, size_t width, diff --git a/src/Simd/SimdSve2Neural.cpp b/src/Simd/SimdSve2Neural.cpp index 9a585cb0fe..adce46f418 100644 --- a/src/Simd/SimdSve2Neural.cpp +++ b/src/Simd/SimdSve2Neural.cpp @@ -118,30 +118,6 @@ namespace Simd //------------------------------------------------------------------------------------------------- - SIMD_INLINE void AddMultiplied(const svbool_t& mask, const svfloat32_t& value, const float* src, float* dst) - { - svst1_f32(mask, dst, svmla_f32_m(mask, svld1_f32(mask, dst), svld1_f32(mask, src), value)); - } - - void NeuralAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst) - { - size_t F = svcntw(), QF = 4 * F, i = 0; - const svbool_t body = svptrue_b32(); - const svfloat32_t _value = svdup_n_f32(value[0]); - - for (; i + QF <= size; i += QF) - { - AddMultiplied(body, _value, src + i + 0 * F, dst + i + 0 * F); - AddMultiplied(body, _value, src + i + 1 * F, dst + i + 1 * F); - AddMultiplied(body, _value, src + i + 2 * F, dst + i + 2 * F); - AddMultiplied(body, _value, src + i + 3 * F, dst + i + 3 * F); - } - for (; i + F <= size; i += F) - AddMultiplied(body, _value, src + i, dst + i); - if (i < size) - AddMultiplied(svwhilelt_b32(i, size), _value, src + i, dst + i); - } - SIMD_INLINE void AddVector(const svbool_t& mask, const float* src, float* dst) { svst1_f32(mask, dst, svadd_f32_x(mask, svld1_f32(mask, dst), svld1_f32(mask, src))); diff --git a/src/Simd/SimdSve2SynetMath.cpp b/src/Simd/SimdSve2SynetMath.cpp new file mode 100644 index 0000000000..9460dc0e29 --- /dev/null +++ b/src/Simd/SimdSve2SynetMath.cpp @@ -0,0 +1,58 @@ +/* +* Simd Library (http://ermig1979.github.io/Simd). +* +* Copyright (c) 2011-2026 Yermalayeu Ihar. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ +#include "Simd/SimdMemory.h" + +namespace Simd +{ +#ifdef SIMD_SVE2_ENABLE +#if defined(SIMD_SYNET_ENABLE) + namespace Sve2 + { + SIMD_INLINE void AddMultiplied(const svbool_t& mask, const svfloat32_t& value, const float* src, float* dst) + { + svst1_f32(mask, dst, svmla_f32_m(mask, svld1_f32(mask, dst), svld1_f32(mask, src), value)); + } + + void SynetAddVectorMultipliedByValue(const float* src, size_t size, const float* value, float* dst) + { + size_t F = svcntw(), QF = 4 * F, i = 0; + const svbool_t body = svptrue_b32(); + const svfloat32_t _value = svdup_n_f32(value[0]); + + for (; i + QF <= size; i += QF) + { + AddMultiplied(body, _value, src + i + 0 * F, dst + i + 0 * F); + AddMultiplied(body, _value, src + i + 1 * F, dst + i + 1 * F); + AddMultiplied(body, _value, src + i + 2 * F, dst + i + 2 * F); + AddMultiplied(body, _value, src + i + 3 * F, dst + i + 3 * F); + } + for (; i + F <= size; i += F) + AddMultiplied(body, _value, src + i, dst + i); + if (i < size) + AddMultiplied(svwhilelt_b32(i, size), _value, src + i, dst + i); + } + } +#endif +#endif +} diff --git a/src/Test/Test.cpp b/src/Test/Test.cpp index 88d6371e07..6744703bad 100644 --- a/src/Test/Test.cpp +++ b/src/Test/Test.cpp @@ -271,7 +271,6 @@ namespace Test TEST_ADD_GROUP_A0(NeuralConvert); TEST_ADD_GROUP_A0(NeuralProductSum); - TEST_ADD_GROUP_A0(NeuralAddVectorMultipliedByValue); TEST_ADD_GROUP_A0(NeuralAddVector); TEST_ADD_GROUP_A0(NeuralAddValue); TEST_ADD_GROUP_A0(NeuralDerivativeSigmoid); @@ -349,6 +348,7 @@ namespace Test #if defined(SIMD_SYNET_ENABLE) TEST_ADD_GROUP_A0(SynetAddBias); + TEST_ADD_GROUP_A0(SynetAddVectorMultipliedByValue); TEST_ADD_GROUP_A0(SynetAdd8i); TEST_ADD_GROUP_A0(SynetAdd16b); diff --git a/src/Test/TestDescrInt.cpp b/src/Test/TestDescrInt.cpp index cfec2ab15e..25755c4c97 100644 --- a/src/Test/TestDescrInt.cpp +++ b/src/Test/TestDescrInt.cpp @@ -787,9 +787,9 @@ namespace Test static inline void SetRandomDescriptor(const float* rnd, size_t size, float mainRange, int seed, float noiseRange, size_t noiseTimes, float* dst) { memset(dst, 0, size * sizeof(float)); - SimdNeuralAddVectorMultipliedByValue(rnd + seed, size, &mainRange, dst); + SimdSynetAddVectorMultipliedByValue(rnd + seed, size, &mainRange, dst); for(size_t t = 0; t < noiseTimes; ++t) - SimdNeuralAddVectorMultipliedByValue(rnd + (Rand() & INT16_MAX), size, &noiseRange, dst); + SimdSynetAddVectorMultipliedByValue(rnd + (Rand() & INT16_MAX), size, &noiseRange, dst); } typedef std::pair Pair; diff --git a/src/Test/TestNeural.cpp b/src/Test/TestNeural.cpp index bb8a2a5eeb..c2115d468f 100644 --- a/src/Test/TestNeural.cpp +++ b/src/Test/TestNeural.cpp @@ -239,99 +239,6 @@ namespace Test return result; } - namespace - { - struct FuncAVMV - { - typedef void(*FuncPtr)(const float * src, size_t size, const float * value, float * dst); - - FuncPtr func; - String description; - - FuncAVMV(const FuncPtr & f, const String & d) : func(f), description(d) {} - - void Call(const View & src, float value, const View & dstSrc, View & dstDst) const - { - Simd::Copy(dstSrc, dstDst); - TEST_PERFORMANCE_TEST(description); - func((float*)src.data, src.width, &value, (float*)dstDst.data); - } - }; - } -#define FUNC_AVMV(function) FuncAVMV(function, #function) - - bool NeuralAddVectorMultipliedByValueAutoTest(int size, float eps, const FuncAVMV & f1, const FuncAVMV & f2) - { - bool result = true; - - TEST_LOG_SS(Info, "Test " << f1.description << " & " << f2.description << " [" << size << "]."); - - View src(size, 1, View::Float, NULL, TEST_ALIGN(size)); - FillRandom32f(src); - - View dstSrc(size, 1, View::Float, NULL, TEST_ALIGN(size)); - FillRandom32f(dstSrc); - - const float value = 0.3f; - - View dstDst1(size, 1, View::Float, NULL, TEST_ALIGN(size)); - View dstDst2(size, 1, View::Float, NULL, TEST_ALIGN(size)); - - TEST_EXECUTE_AT_LEAST_MIN_TIME(f1.Call(src, value, dstSrc, dstDst1)); - - TEST_EXECUTE_AT_LEAST_MIN_TIME(f2.Call(src, value, dstSrc, dstDst2)); - - result = Compare(dstDst1, dstDst2, eps, true); - - return result; - } - - bool NeuralAddVectorMultipliedByValueAutoTest(float eps, const FuncAVMV & f1, const FuncAVMV & f2) - { - bool result = true; - - result = result && NeuralAddVectorMultipliedByValueAutoTest(W*H, eps, f1, f2); - result = result && NeuralAddVectorMultipliedByValueAutoTest(W*H + O, eps, f1, f2); - result = result && NeuralAddVectorMultipliedByValueAutoTest(W*H - O, eps, f1, f2); - - return result; - } - - bool NeuralAddVectorMultipliedByValueAutoTest(const Options & options) - { - bool result = true; - - if (TestBase(options)) - result = result && NeuralAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Base::NeuralAddVectorMultipliedByValue), FUNC_AVMV(SimdNeuralAddVectorMultipliedByValue)); - -#ifdef SIMD_SSE41_ENABLE - if (Simd::Sse41::Enable && TestSse41(options)) - result = result && NeuralAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Sse41::NeuralAddVectorMultipliedByValue), FUNC_AVMV(SimdNeuralAddVectorMultipliedByValue)); -#endif - -#ifdef SIMD_AVX2_ENABLE - if (Simd::Avx2::Enable && TestAvx2(options)) - result = result && NeuralAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Avx2::NeuralAddVectorMultipliedByValue), FUNC_AVMV(SimdNeuralAddVectorMultipliedByValue)); -#endif - -#ifdef SIMD_AVX512BW_ENABLE - if (Simd::Avx512bw::Enable && TestAvx512bw(options)) - result = result && NeuralAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Avx512bw::NeuralAddVectorMultipliedByValue), FUNC_AVMV(SimdNeuralAddVectorMultipliedByValue)); -#endif - -#ifdef SIMD_SVE2_ENABLE - if (Simd::Sve2::Enable && TestSve2(options)) - result = result && NeuralAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Sve2::NeuralAddVectorMultipliedByValue), FUNC_AVMV(SimdNeuralAddVectorMultipliedByValue)); -#endif - -#ifdef SIMD_NEON_ENABLE - if (Simd::Neon::Enable && TestNeon(options)) - result = result && NeuralAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Neon::NeuralAddVectorMultipliedByValue), FUNC_AVMV(SimdNeuralAddVectorMultipliedByValue)); -#endif - - return result; - } - namespace { struct FuncAddVec diff --git a/src/Test/TestSynetMath.cpp b/src/Test/TestSynetMath.cpp new file mode 100644 index 0000000000..9279109ef7 --- /dev/null +++ b/src/Test/TestSynetMath.cpp @@ -0,0 +1,125 @@ +/* +* Tests for Simd Library (http://ermig1979.github.io/Simd). +* +* Copyright (c) 2011-2026 Yermalayeu Ihar. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ +#include "Test/TestCompare.h" +#include "Test/TestPerformance.h" +#include "Test/TestRandom.h" +#include "Test/TestOptions.h" + +namespace Test +{ +#if defined(SIMD_SYNET_ENABLE) + namespace + { + struct FuncAVMV + { + typedef void(*FuncPtr)(const float * src, size_t size, const float * value, float * dst); + + FuncPtr func; + String description; + + FuncAVMV(const FuncPtr & f, const String & d) : func(f), description(d) {} + + void Call(const View & src, float value, const View & dstSrc, View & dstDst) const + { + Simd::Copy(dstSrc, dstDst); + TEST_PERFORMANCE_TEST(description); + func((float*)src.data, src.width, &value, (float*)dstDst.data); + } + }; + } +#define FUNC_AVMV(function) FuncAVMV(function, #function) + + bool SynetAddVectorMultipliedByValueAutoTest(int size, float eps, const FuncAVMV & f1, const FuncAVMV & f2) + { + bool result = true; + + TEST_LOG_SS(Info, "Test " << f1.description << " & " << f2.description << " [" << size << "]."); + + View src(size, 1, View::Float, NULL, TEST_ALIGN(size)); + FillRandom32f(src); + + View dstSrc(size, 1, View::Float, NULL, TEST_ALIGN(size)); + FillRandom32f(dstSrc); + + const float value = 0.3f; + + View dstDst1(size, 1, View::Float, NULL, TEST_ALIGN(size)); + View dstDst2(size, 1, View::Float, NULL, TEST_ALIGN(size)); + + TEST_EXECUTE_AT_LEAST_MIN_TIME(f1.Call(src, value, dstSrc, dstDst1)); + + TEST_EXECUTE_AT_LEAST_MIN_TIME(f2.Call(src, value, dstSrc, dstDst2)); + + result = Compare(dstDst1, dstDst2, eps, true); + + return result; + } + + bool SynetAddVectorMultipliedByValueAutoTest(float eps, const FuncAVMV & f1, const FuncAVMV & f2) + { + bool result = true; + + result = result && SynetAddVectorMultipliedByValueAutoTest(W*H, eps, f1, f2); + result = result && SynetAddVectorMultipliedByValueAutoTest(W*H + O, eps, f1, f2); + result = result && SynetAddVectorMultipliedByValueAutoTest(W*H - O, eps, f1, f2); + + return result; + } + + bool SynetAddVectorMultipliedByValueAutoTest(const Options & options) + { + bool result = true; + + if (TestBase(options)) + result = result && SynetAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Base::SynetAddVectorMultipliedByValue), FUNC_AVMV(SimdSynetAddVectorMultipliedByValue)); + +#ifdef SIMD_SSE41_ENABLE + if (Simd::Sse41::Enable && TestSse41(options)) + result = result && SynetAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Sse41::SynetAddVectorMultipliedByValue), FUNC_AVMV(SimdSynetAddVectorMultipliedByValue)); +#endif + +#ifdef SIMD_AVX2_ENABLE + if (Simd::Avx2::Enable && TestAvx2(options)) + result = result && SynetAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Avx2::SynetAddVectorMultipliedByValue), FUNC_AVMV(SimdSynetAddVectorMultipliedByValue)); +#endif + +#ifdef SIMD_AVX512BW_ENABLE + if (Simd::Avx512bw::Enable && TestAvx512bw(options)) + result = result && SynetAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Avx512bw::SynetAddVectorMultipliedByValue), FUNC_AVMV(SimdSynetAddVectorMultipliedByValue)); +#endif + +#ifdef SIMD_SVE2_ENABLE + if (Simd::Sve2::Enable && TestSve2(options)) + result = result && SynetAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Sve2::SynetAddVectorMultipliedByValue), FUNC_AVMV(SimdSynetAddVectorMultipliedByValue)); +#endif + +#ifdef SIMD_NEON_ENABLE + if (Simd::Neon::Enable && TestNeon(options)) + result = result && SynetAddVectorMultipliedByValueAutoTest(EPS, FUNC_AVMV(Simd::Neon::SynetAddVectorMultipliedByValue), FUNC_AVMV(SimdSynetAddVectorMultipliedByValue)); +#endif + + return result; + } +#endif +}