You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Have questions about stdlib? Need help fixing a bug, figuring out what to do next, or just looking for feedback? Join our weekly office hours to connect with project maintainers, stay updated on the latest project news, and chat with other community members. This is a great opportunity to ask questions, share ideas, and engage directly with the stdlib team.
Following Office Hours #150 and the Highway/DAXPY draft PR #13068, I wanted to narrow the question before suggesting any broader SIMD direction. I have not changed upstream source or opened a PR. The goal was to identify what an actual package prototype should test.
I began with DAXPY because it was already being explored in the Highway draft and offered a simple C ABI baseline. To see whether its result generalized, I then chose representative workloads for different constraints. DDOT covered reduction ordering. DABS and the sampled generated ADD signatures covered callback and generation boundaries. DCBRT covered vector math and numerical accuracy. DSUMPW, observed through DMEANPW, covered a reduction with independent accumulators and a fixed combination tree. These were probes for different questions rather than equal rollout candidates, so I compared the methods relevant to each constraint.
Those probes produced different outcomes. Optimized plain C was already strong for DAXPY, and DDOT exposed the numerical consequences of changing the reduction order. In the scratch comparisons, callback removal explained most gains for DABS and the sampled generated ADD signatures. DCBRT separated bounded error vector math from an exact current result path dependent on link time optimization and symbol visibility. DSUMPW provided the clearest evidence of explicit SIMD beyond specialized C. Each base reduction uses eight logical accumulators, so I could pack their updates for contiguous inputs while preserving their addition order and the final combination tree. Under that constraint, direct compiler intrinsics, SIMDe, xsimd, and Highway matched the current implementation on the tested corpus and showed repeatable gains at large contiguous N on one x86 host and in direct WebAssembly runs in headless Chrome and Firefox. I therefore prioritized DSUMPW for the first package prototype.
Would it be useful for me to implement and test a prototype in the actual DSUMPW package using stdlib鈥檚 existing build, tests, and benchmarks? I would keep the C ABI, scalar fallback, and current reduction order unchanged. The goal would be to see whether the performance gains remain after integration and justify the added complexity and size before discussing a backend or broader rollout.
P.S. I鈥檓 sorry I will not be able to attend today鈥檚 Office Hours because I was not feeling well. I would appreciate any feedback you can leave either in the Zulip thread or here, and I鈥檒l make sure to follow up on it.
To implement native C bindings for stats/base/ndarray/ packages like dstdev and dvariance, I noticed an architectural pattern that differs from the single-array packages I've recently worked on, and I'd love to get some guidance.
For these packages, the user provides a data array and a zero-dimensional ndarray for the correction (degrees of freedom adjustment).
In the JavaScript wrapper for ndarray/dstdev, it handles the translation to a primitive number for the strided layer like this:
// stats/base/ndarray/dstdev/lib/main.jsfunctiondstdev(arrays){varcorrection;varx=arrays[0];// Extracts the scalar from the 0-dim ndarraycorrection=ndarraylike2scalar(arrays[1]);// Passes it to strided as a primitive numberreturnstrided(numelDimension(x,0),correction,getData(x), ... );}
Conversely, the underlying strided package's C addon expects that primitive number directly:
// stats/strided/dstdev/src/addon.cstaticnapi_valueaddon( napi_envenv, napi_callback_infoinfo ) {
// ...// Extracts the correction as a primitive doubleSTDLIB_NAPI_ARGV_DOUBLE( env, correction, argv, 1 );
// ...
}
My question is: When we write addon.c for these ndarray packages, we will be receiving the arrays array containing the 0-dim ndarray object, so we can't simply use STDLIB_NAPI_ARGV_DOUBLE like the strided package did.
What is the recommended approach for handling this in C? Once we extract the zero-dimensional ndarray using stdlib_ndarray_napi_addon_arguments, how should we properly extract its underlying scalar double value so that we can pass it down to the strided C function?
These notes are likely imperfect, especially when it comes to spelling/function/package names
Meeting Purpose
Discussing technical challenges and development strategy for stdlib.
Key Takeaways
String Arrays: Prioritize a CPU-based implementation, studying the NumPy RFC for its 3 allocation strategies. WebGPU is premature due to the async execution model, CPU-GPU transfer overhead, and the need for a unified device management strategy.
ndarray C Implementations: Use stdlib.ndarray.getFloat64 to extract scalar values from 0D arrays, avoiding manual buffer access. A single, generalized tracking issue will replace specific ones to manage the moving target of new APIs.
FFT Workspace: The float32 workspace for decompose is acceptable for practical sequence lengths (~50k). A performance benchmark will compare float32 vs. int32 views for very large sequences (>16.7M) to assess the risk of rounding errors.
PCG32 Fixtures: Generate fixtures using a small, custom C wrapper for the original PCG32 implementation. Standardize test messages to "returns expected value" to enable future automated, verbose error reporting.
Topics
ndarray C Implementations & Tracking
Problem: Extracting scalar values from 0D ndarray arguments for C functions.
Solution: Use the dedicated stdlib.ndarray.getFloat64 API to extract the value directly, avoiding manual buffer manipulation.
Problem: Duplicate PRs for ndarray C implementations due to a lack of a central tracking issue.
Solution: Create one generalized tracking issue instead of specific ones, as the set of APIs is a moving target.
Scope: Any blas-extended-base/ndarray API with a JavaScript wrapper but no C implementation.
Process: Comment on the issue to claim a task and use a standardized PR title (e.g., feature: add C implementation to <package>) to prevent conflicts.
String Arrays on WebGPU
Proposal: Implement GPU-accelerated string arrays via WebGPU, inspired by NVIDIA's cuDF.
Decision: Defer WebGPU. A CPU-based implementation is the necessary first step to define the core API and understand the JavaScript-C/WASM bridge.
Rationale for Deferring WebGPU:
Execution Model: WebGPU is async, requiring a computational graph (like PyTorch/Jax) to queue operations and manage state.
Overhead: CPU-GPU data transfer is a bottleneck for smaller datasets.
Device Management:stdlib lacks a unified strategy for device types (CPU, WASM, GPU), which would be an "infectious" change across the entire API.
Data Type Support: WebGPU has limited native data type support (e.g., no int64), requiring emulation.
FFT Workspace Data Type
Context: The decompose function in the FFT implementation uses a float32 workspace for integer factors.
Risk: For very large sequence lengths (>16.7M), float32 lacks the precision to represent all integers, potentially causing rounding errors. The original rFFT library uses an int32 view of the buffer to avoid this.
Decision: Proceed with float32 for now.
Rationale: Practical FFT sequence lengths are much smaller (~50k), making the risk negligible.
Future Path: If needed, a simple refactor can create an int32 view of the buffer for decompose without reallocating memory.
PCG32 Fixture Generation
Problem: Generating test fixtures for PCG32 requires using the original C library, which has multiple versions and a large codebase.
Solution: Create a small, custom C wrapper for the original PCG32 implementation to generate the required JSON fixtures.
Process: Generate the JSON file independently and commit it to the repository.
Standardization:
Test Messages: Standardize all test messages to "returns expected value." This enables future automated, verbose error reporting.
Seed Value: Use a consistent seed (e.g., 12345) across JavaScript and C examples to simplify divergence detection.
TypeScript: Add the missing normalized function declaration to the MersenneTwister TypeScript file**.**
ESLint Configuration Issue
Problem: Recent ESLint configuration changes are causing new, unexpected lint errors (e.g., in READMEs), breaking CI.
Action: Philipp will lint a large portion of the project with the new config to identify and fix the problematic rules.
Activity
manit2004 commentedon Aug 25, 2026
blas/base/sgemmtr): adding lib, test, docs, examples, benchmark 聽stdlib#14415teddygood commentedon Aug 25, 2026
Following Office Hours #150 and the Highway/DAXPY draft PR #13068, I wanted to narrow the question before suggesting any broader SIMD direction. I have not changed upstream source or opened a PR. The goal was to identify what an actual package prototype should test.
I began with DAXPY because it was already being explored in the Highway draft and offered a simple C ABI baseline. To see whether its result generalized, I then chose representative workloads for different constraints. DDOT covered reduction ordering. DABS and the sampled generated ADD signatures covered callback and generation boundaries. DCBRT covered vector math and numerical accuracy. DSUMPW, observed through DMEANPW, covered a reduction with independent accumulators and a fixed combination tree. These were probes for different questions rather than equal rollout candidates, so I compared the methods relevant to each constraint.
Those probes produced different outcomes. Optimized plain C was already strong for DAXPY, and DDOT exposed the numerical consequences of changing the reduction order. In the scratch comparisons, callback removal explained most gains for DABS and the sampled generated ADD signatures. DCBRT separated bounded error vector math from an exact current result path dependent on link time optimization and symbol visibility. DSUMPW provided the clearest evidence of explicit SIMD beyond specialized C. Each base reduction uses eight logical accumulators, so I could pack their updates for contiguous inputs while preserving their addition order and the final combination tree. Under that constraint, direct compiler intrinsics, SIMDe, xsimd, and Highway matched the current implementation on the tested corpus and showed repeatable gains at large contiguous N on one x86 host and in direct WebAssembly runs in headless Chrome and Firefox. I therefore prioritized DSUMPW for the first package prototype.
Would it be useful for me to implement and test a prototype in the actual DSUMPW package using stdlib鈥檚 existing build, tests, and benchmarks? I would keep the C ABI, scalar fallback, and current reduction order unchanged. The goal would be to see whether the performance gains remain after integration and justify the added complexity and size before discussing a backend or broader rollout.
P.S. I鈥檓 sorry I will not be able to attend today鈥檚 Office Hours because I was not feeling well. I would appreciate any feedback you can leave either in the Zulip thread or here, and I鈥檒l make sure to follow up on it.
ujjwalv01 commentedon Aug 25, 2026
To implement native C bindings for
stats/base/ndarray/packages likedstdevanddvariance, I noticed an architectural pattern that differs from the single-array packages I've recently worked on, and I'd love to get some guidance.For these packages, the user provides a data array and a zero-dimensional ndarray for the
correction(degrees of freedom adjustment).In the JavaScript wrapper for
ndarray/dstdev, it handles the translation to a primitive number for the strided layer like this:Conversely, the underlying strided package's C addon expects that primitive number directly:
My question is: When we write
addon.cfor thesendarraypackages, we will be receiving thearraysarray containing the 0-dim ndarray object, so we can't simply useSTDLIB_NAPI_ARGV_DOUBLElike the strided package did.What is the recommended approach for handling this in C? Once we extract the zero-dimensional ndarray using
stdlib_ndarray_napi_addon_arguments, how should we properly extract its underlying scalar double value so that we can pass it down to thestridedC function?gunjjoshi commentedon Aug 25, 2026
Discussion around stdlib-js/stdlib#14591 (review), and how we want to plan implementing packages further, in the FFT namespace.
0PrashantYadav0 commentedon Aug 25, 2026
Is this looks good ?
batpigandme commentedon Aug 25, 2026
AI-Generated Summary
Caution
These notes are likely imperfect, especially when it comes to spelling/function/package names
Meeting Purpose
Discussing technical challenges and development strategy for
stdlib.Key Takeaways
ndarrayC Implementations: Usestdlib.ndarray.getFloat64to extract scalar values from 0D arrays, avoiding manual buffer access. A single, generalized tracking issue will replace specific ones to manage the moving target of new APIs.float32workspace fordecomposeis acceptable for practical sequence lengths (~50k). A performance benchmark will comparefloat32vs.int32views for very large sequences (>16.7M) to assess the risk of rounding errors.Topics
ndarrayC Implementations & Trackingndarrayarguments for C functions.stdlib.ndarray.getFloat64API to extract the value directly, avoiding manual buffer manipulation.ndarrayC implementations due to a lack of a central tracking issue.blas-extended-base/ndarrayAPI with a JavaScript wrapper but no C implementation.feature: add C implementation to <package>) to prevent conflicts.String Arrays on WebGPU
Proposal: Implement GPU-accelerated string arrays via WebGPU, inspired by NVIDIA's
cuDF.Decision: Defer WebGPU. A CPU-based implementation is the necessary first step to define the core API and understand the JavaScript-C/WASM bridge.
Rationale for Deferring WebGPU:
stdliblacks a unified strategy for device types (CPU, WASM, GPU), which would be an "infectious" change across the entire API.int64), requiring emulation.FFT Workspace Data Type
Context: The
decomposefunction in the FFT implementation uses afloat32workspace for integer factors.Risk: For very large sequence lengths (>16.7M),
float32lacks the precision to represent all integers, potentially causing rounding errors. The originalrFFTlibrary uses anint32view of the buffer to avoid this.Decision: Proceed with
float32for now.int32view of the buffer fordecomposewithout reallocating memory.PCG32 Fixture Generation
Problem: Generating test fixtures for PCG32 requires using the original C library, which has multiple versions and a large codebase.
Solution: Create a small, custom C wrapper for the original PCG32 implementation to generate the required JSON fixtures.
Standardization:
12345) across JavaScript and C examples to simplify divergence detection.normalizedfunction declaration to theMersenneTwisterTypeScript file**.**ESLint Configuration Issue
Problem: Recent ESLint configuration changes are causing new, unexpected lint errors (e.g., in READMEs), breaking CI.
Action: Philipp will lint a large portion of the project with the new config to identify and fix the problematic rules.
Full transcript
Full office hours transcript