Repository navigation
Float32 results from the Workspace; cheaper range check in the AVX2 log - #94
Merged
Merged
Conversation
Through the API, float32 Log was 1.25x NumPy at 16 Ki on Zen 3 although its kernel was at parity: the result's make costs 4.1 us there (a large span taken from the heap and zeroed), and the Workspace only handed out float64, so a Float32 result went to the heap even inside one. Workspace.alloc32 carves float32 storage from the same blocks (two per float64 element, 64-byte aligned, cap = len). unary32 (Exp, Log), the float32 ufuncs, arithmetic, Power, Clip and the float32 GEMM (zeroed) use it. TestWorkspace32MatchesHeap holds every site to the heap bit for bit, also on a NaN-poisoned arena; an unzeroed GEMM allocation fails it. In a Workspace, float32 Log goes from 35.3 to 30.6 us at 16 Ki. log32CRAVX2 now rejects non-positive-normal lanes at the end of the block with one wrapping add and one compare, instead of a five-instruction test and a branch before the arithmetic: -2.4% (abbench, 8 rounds). BenchmarkLog32Kernels gains the API's data set, 1 Mi, and the count of blocks handed back to logCR; BenchmarkDTypeExpLogWS is new. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measured on one Zen 3 core with the load at most 4.2: in a Workspace, float32 Exp is about 12% faster than NumPy and Log about 5% slower. The README no longer claims API-level parity for both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Nov 7, 2026
tannevaled
added a commit
that referenced
this pull request
Nov 7, 2026
…xp, log (K1) (#97) * kernels: import go-simd/floats for sum, elementwise, extrema, clip, exp, log (K1) K1 of the go-scikit performance campaign (go-scikit/roadmap#27): ndarray now imports go-simd/floats v0.9.0 and deletes its copies. - exp, log, and the correctly rounded float32 exp/log (with the AVX2 kernels of #94/#96 and the NEON kernel of #95, now go-simd/floats#29): deleted here (Go sources, tests, generator kernels, assembly); Exp, Log, Exp32, Log32 and their P forms call floats. - amd64 and arm64: the sum/sqrt/max/min/add/sub/mul/div kernels are floats'; Clip is floats.ClampScalar. Max/Min resolve a zero result with the serial oracle (floats leaves the sign of zero unspecified). - Sum is floats.SumPairwise on every architecture: NumPy's order, bit-identical to np.sum; serial at every size. A changed last bit is the fix; the golden values of TestSumMatchesNumPy are NumPy 2.5.4's. - Not moved: the float32 elementwise/sqrt/extremum/AddBlocks8F32 kernels, the dot inside GEMM/Dot1D, and the ppc64le, loong64, riscv64 and s390x kernels (floats has none for them yet). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * kernels: test the parallel exp/log forms and Log10 (100% coverage gate) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Float32 results now come from the
Workspace, and the AVX2 log kernel's range check is cheaper. This also corrects a README claim made in v0.34.0.What was wrong: through the API, float32
Logwas 1.25× NumPy at 16 Ki on Zen 3, although its kernel was at parity. The README said it ran "as fast as NumPy".makealone costs 4.1 µs at 16 Ki and 130 µs at 1 Mi on that core (a large span from the heap, zeroed). Kernel plus allocation adds up to the API time at both sizes.handed-blocks/opmetric).Workspace, the library's answer to allocation, only handed out float64, so a Float32 result went to the heap even inside one.Changes:
Workspace.alloc32carves float32 storage from the same blocks: two per float64 element, 64-byte aligned, cap = len. It is used byExp,Log, the other float32 ufuncs, arithmetic,Power,Clipand the float32 GEMM (zeroed there, because it accumulates).TestWorkspace32MatchesHeapholds every site to the heap result bit for bit, including on an arena filled with NaN bits. Making the GEMM's allocation unzeroed makes it fail (checked).TestWorkspaceAlloc32Shapechecks length, cap, alignment and zeroing;TestWorkspace32Allocateschecks the allocation count.log32CRAVX2rejects lanes that are not positive normals at the end of the block. One wrapping add and one compare (ux + 0x7f800000 ≤ −0x01000001 as int32, exact because adding a constant mod 2³² is a bijection) replace five instructions and a branch. That is −2.4% (abbench, 8 rounds, p ≤ 0.03 on three of four sizes).TestLog32CorrectlyRoundedover all 2³² inputs finds 0 incorrectly rounded.Expin a Workspacenp.expLog, allocating (v0.34.0: 35.5 µs)Login a Workspacenp.logIn a Workspace,
Expis about 12% faster than NumPy andLogabout 5% slower. The README anddocs/perf.mdnow say exactly that. Coverage of the package stays at 100%.SECURITY.mdhas the audit entry for theunsafe.Sliceinalloc32.🤖 Generated with Claude Code