From b82f5b59f7c1717502b2add6852d11ff89f0e9ba Mon Sep 17 00:00:00 2001 From: anematode Date: Tue, 19 May 2026 18:37:09 +0200 Subject: [PATCH] Port sqr_clipped_relu.h to NEON Passed STC (https://tests.stockfishchess.org/tests/view/69fd70c39392f0c317213b99) LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 315360 W: 80995 L: 80315 D: 154050 Ptnml(0-2): 573, 33687, 88501, 34325, 594 Data from vondele: ``` ==== master ==== 1 Nodes/second : 278894157 2 Nodes/second : 279192601 3 Nodes/second : 278279517 Average (over 3): 278788758 ==== neonnnn ==== 1 Nodes/second : 280614075 2 Nodes/second : 279971502 3 Nodes/second : 280613919 Average (over 3): 280399832 ``` closes https://github.com/official-stockfish/Stockfish/pull/6820 No functional change --- src/nnue/layers/sqr_clipped_relu.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/nnue/layers/sqr_clipped_relu.h b/src/nnue/layers/sqr_clipped_relu.h index e45f6f0f1..08e6d3d33 100644 --- a/src/nnue/layers/sqr_clipped_relu.h +++ b/src/nnue/layers/sqr_clipped_relu.h @@ -26,6 +26,7 @@ #include #include "../nnue_common.h" +#include "../simd.h" namespace Stockfish::Eval::NNUE::Layers { @@ -120,6 +121,25 @@ class SqrClippedReLU { } constexpr IndexType Start = NumChunks * 16; +#elif defined(USE_NEON) + static_assert(WeightScaleBits == 6); + constexpr IndexType NumChunks = InputDimensions / 16; + const auto in = reinterpret_cast(input); + const auto out = reinterpret_cast(output); + for (IndexType i = 0; i < NumChunks; ++i) + { + const int16x8_t words0 = + vcombine_s16(vqmovn_s32(in[i * 4 + 0]), vqmovn_s32(in[i * 4 + 1])); + const int16x8_t words1 = + vcombine_s16(vqmovn_s32(in[i * 4 + 2]), vqmovn_s32(in[i * 4 + 3])); + + const int16x8_t r0 = vshrq_n_s16(vqdmulhq_s16(words0, words0), 4); + const int16x8_t r1 = vshrq_n_s16(vqdmulhq_s16(words1, words1), 4); + + out[i] = vcombine_s8(vqmovn_s16(r0), vqmovn_s16(r1)); + } + constexpr IndexType Start = NumChunks * 16; + #else constexpr IndexType Start = 0; #endif