Skip to content

feat(ai): add stable softmax, normalization and activation kernels - #35

Draft
damian123 wants to merge 11 commits into
andyD123:mainfrom
damian123:feat/neural-kernels
Draft

feat(ai): add stable softmax, normalization and activation kernels#35
damian123 wants to merge 11 commits into
andyD123:mainfrom
damian123:feat/neural-kernels

Conversation

@damian123

@damian123 damian123 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

This is a focused three-file delta on top of #34:

  • Vectorisation/VecX/neural_kernels.h
  • VectorTest/TestNeuralKernels.cpp
  • VectorTest/CMakeLists.txt

Review the incremental #34 to #35 diff.

It adds AVX2 VecF8F preprocessing kernels for:

  • softmax, log-softmax, and log-sum-exp
  • LayerNorm and RMSNorm
  • ReLU, Leaky ReLU, Sigmoid, Tanh, approximate GELU, and SiLU
  • clipping and bias-plus-activation
  • exact in-place and out-of-place operation

Numerical contracts

  • Softmax-family kernels subtract the logical maximum before exponentiation. Their sums visit only the first n values, in index order, and accumulate in double precision; SIMD padding never participates.
  • LayerNorm uses population variance and preserves the residual of its double-precision mean when centering float32 values. RMSNorm uses mean square. Both apply finite, positive epsilon inside the square root.
  • Inputs and optional affine arrays must be finite. NaN and infinity are rejected with std::invalid_argument rather than producing accidental non-finite results.
  • Leaky ReLU alpha must be finite and non-negative. Clip bounds must be finite and ordered.
  • Buffers are contiguous float32 arrays. Caller alignment is not required, and logical sizes below, at, and above the eight-float SIMD width are supported.
  • Exact input/output aliasing is supported. Arbitrary partial overlap is outside the contract.
  • Empty log-sum-exp returns negative infinity; other empty-buffer operations are no-ops after parameter validation.
  • Reduction order is deterministic. Cross-compiler floating-point results are compared to independent scalar-double references with stated tolerances, not bit identity.

Verification

  • 15 deterministic focused tests cover width-8 boundaries (1, 7, 8, 9, 15, 16, 17), deliberately unaligned buffers, output canaries, exact aliases, extreme finite logits, non-finite rejection, zero variance, epsilon-dominant inputs, and scalar-double error metrics.
  • GCC 13.3 Release: full build including examples; 8/8 CTest entries passed.
  • Clang 18.1 Release: 4/4 focused CTest entries passed.
  • GCC 13.3 Debug with ASan/UBSan: 4/4 focused CTest entries passed.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DDR3_BUILD_TESTS=ON -DDR3_BUILD_EXAMPLES=OFF -DDR3_ISA=AVX2
cmake --build build --config Release --target VectorTest
ctest --test-dir build -C Release -R 'Softmax|LayerNorm|RMSNorm|Activation' --output-on-failure

Non-goals

  • No training loop.
  • No autograd or gradient tape.
  • No tensor abstraction, model loader, or general inference runtime.
  • No AVX-512-specific path until the maintainer opts into that direction.
  • No universal performance claim.

This PR remains a draft pending #34 and maintainer guidance on final component placement.

Register the AVX2 VectorTest suite with CMake/CTest, fetch GoogleTest
portably, pin GitHub Actions, and run tests on Windows MSVC and Ubuntu
GCC/Clang. Fix Span::empty to compare instead of assign so Clang
builds. Keep the portable translation units on all compilers; extra
MSVC-only sources remain opt-in.
Share a single AllAllocatorsGuard in testNamespace.cpp so MSVC does
not see a duplicate symbol. Drop the extra MSVC-only VectorTest
sources from the portable target. Exclude ApplyFilterB from CTest
(fails in Debug). Do not fail the required matrix on known allocator
ASan teardown reports.
CMake 4.x POST_BUILD discovery fails on Windows multi-config
generators. Register the portable suite as a single CTest entry.
AllAllocatorsGuard in other TUs ran after the static unordered_map
members were destroyed, so VectorTest segfaulted on Windows after
gtest had already reported 29/29 passed. Store the size-to-policy
map on the heap and reset the cached policy pointer in freeAll.
Float32 AVX2 (VecF8F) kernels for dot product, squared L2, cosine,
L2 normalization, and bounded-heap top-k over a row-major corpus.
Scalar double is the reference. Zero-norm cosine is a 0 sentinel;
mismatched lengths throw; ties break by smaller row index.
@damian123
damian123 force-pushed the feat/neural-kernels branch from fd57918 to 6b1c372 Compare August 30, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant